Cuadrados mágicos ambiguos de números romanos


10

El rey de la Antigua Roma está teniendo dificultades para determinar si un cuadrado mágico es válido o no, porque el cuadrado mágico que está revisando no incluye ningún separador entre los números. Ha contratado a un ingeniero de software para que lo ayude a determinar si un cuadrado mágico es válido o no.

Descripción de entrada

La entrada entra en STDIN o argumentos de línea de comando No puede tener la entrada preinicializada en una variable (por ejemplo, "este programa espera la entrada en una variable x"). La entrada tiene el siguiente formato:

<top>,<middle>,<bottom>

Cada uno de <top>, <middle>y <bottom>es una cadena que sólo alguna vez contendrá los caracteres en mayúscula I, Vy X. No contendrá espacios ni ningún otro carácter. Cada cadena representa tres números romanos, lo que resulta en una matriz de números 3x3. Sin embargo, estos números romanos pueden (pero no necesariamente) ser ambiguos . Permítanme ilustrar esto con un ejemplo. Considere la siguiente fila de ejemplo de tres números romanos, sin espacios entre cada número:

IVIIIIX

Debido a que no hay espacios entre las letras, hay dos posibilidades para los números aquí:

  • 1, 8, 9 ( I VIII IX)
  • 4, 3, 9 ( IV III IX)

Cuando considera que las tres filas de la matriz pueden ser ambiguas, existe la posibilidad de que haya muchas matrices 3x3 diferentes a partir de una sola entrada.

Tenga en cuenta que secuencias como 1, 7, 1, 9 ( I VII I IX) no son posibles porque cada fila siempre representará tres números romanos. También tenga en cuenta que los números romanos deben ser válidos, por lo que las secuencias como 1, 7, 8 ( I VII IIX) tampoco son posibles.

Descripción de salida

Salida:

  • Un número entero A, donde Aes el número de matrices 3x3 únicas que se pueden formar a partir de la entrada ambigua, y:
  • Un valor verdadero si alguna de las matrices únicas de 3x3 forma un cuadrado mágico, o:
  • Un valor falso si ninguna de las matrices únicas de 3x3 forma un cuadrado mágico.

Los valores de verdad y falsedad deben ser consistentes. Están separados por una coma.

Se requiere alguna explicación sobre lo que se cuenta como único. Mientras una matriz no tenga exactamente los mismos números en exactamente las mismas posiciones que una matriz encontrada previamente, se cuenta como única. Esto significa que las reflexiones, etc. de las matrices encontradas previamente se cuentan como únicas.

Ejemplo de entradas y salidas

En estos ejemplos, uso truecomo mi valor verdadero y falsecomo mi valor falso.

Entrada: VIIIIVI,IIIVVII,IVIXII Salida: 24,true (El triángulo mágico es 8-1-6, 3-5-7, 4-9-2.)

Entrada: IIIXVIII,IVIII,VIIII Salida:210,false

Extras

  • No está permitido usar funciones de conversión de números romanos incorporadas si el idioma elegido tiene una.

"rey de la antigua Roma" ... ¿Emperador?
Digital Trauma

8
@DigitalTrauma Está ambientado en un universo alternativo donde la Antigua Roma tenía un rey, cuadrados mágicos e ingenieros de software. O algo por el estilo ...
absenta

Además, debe usar un interpunct (·) en lugar de una coma ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump

Tengo "24, verdadero" para el primero, pero "210, falso" para el segundo ejemplo. Investigaré
coredump

1
@DigitalTrauma Roma tuvo reyes hasta aproximadamente 509 a. C.
Jon B

Respuestas:


4

Perl, 219 237

Saltos de línea añadidos para mayor claridad.

#!perl -p
%x=(I,1,IV,4,V,5,IX,9,X,10);
$a="(X{0,3}(?:V?I{1,3}|I?V|IX)|X{1,3})"x3;
m*^$a,$a,$a$(?{
  @z=map"$$_",0..9;
  $r|=!grep$x-$_,map{$x=eval s/./ $z[$&]/gr=~s/IX|IV|\S/+$x{$&}/gr}123,456,789,147,258,369,159,357;
  ++$-
})^*;
$_="$-,$r"

Ponme a prueba .


4

Prólogo - 686

:-lib(util),lib(sd). r(S,R):-string_list(S,L),g(L,R). g(L,[N1,N2,N3]):-append(L1,X,L),append(L2,L3,X),n(L1,N1),n(L2,N2),n(L3,N3). n([73,86],4). n([73,88],9). n([73,73,73],3). n([73,73],2). n([73],1). n([86],5). n([86|N],D):-n(N,E),E<4,D is E+5. n([88|N],D):-n(N,E),D is E+10. n([88],10). m(M,[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3]):-split_string(M,",","",[X,Y,Z]),r(X,[X1,X2,X3]),r(Y,[Y1,Y2,Y3]),r(Z,[Z1,Z2,Z3]). a(L):-alldifferent(L),L=[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3],l(X1,X2,X3,T),l(Y1,Y2,Y3,T),l(Z1,Z2,Z3,T),l(X1,Y1,Z1,T),l(X2,Y2,Z2,T),l(X3,Y3,Z3,T). l(A,B,C,T):-T is A+B+C. p:-read_line(S),findall(L,m(S,L),A),length(A,C),findall(L,(member(L,A),a(L)),B),(B=[_|_]->R=true;R=false),writeln((C,R)).

Sin golf

% I : 73
% V : 86
% X : 88
:-lib(util).
:-lib(sd).
r(S,R) :- string_list(S,L), g(L,R).
g(L,[N1,N2,N3]):-
    append(L1,X,L),
    append(L2,L3,X),
    n(L1,N1),n(L2,N2),n(L3,N3).
n([73,86],4).
n([73,88],9).
n([73,73,73],3).
n([73,73],2).
n([73],1).
n([86],5).
n([86|N],D):-n(N,E),E<4,D is E+5.
n([88|N],D):-n(N,E), D is E+10.
n([88],10).
m(M,[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3]) :-
    split_string(M,",","",[X,Y,Z]),
    r(X,[X1,X2,X3]),
    r(Y,[Y1,Y2,Y3]),
    r(Z,[Z1,Z2,Z3]).
a(L) :-
    alldifferent(L),
    L=[X1,X2,X3,Y1,Y2,Y3,Z1,Z2,Z3],
    l(X1,X2,X3,T),
    l(Y1,Y2,Y3,T),
    l(Z1,Z2,Z3,T),
    l(X1,Y1,Z1,T),
    l(X2,Y2,Z2,T),
    l(X3,Y3,Z3,T).
l(A,B,C,T):-T is A+B+C.
p :- read_line(S),
     findall(L,m(S,L),A),
     length(A,C),
     findall(L,(member(L,A),a(L)),B),
     (B=[_|_]->R=true;R=false),
     writeln((C,R)).

Por supuesto, ptambién podría definirse como:

p :- read_line(S),
     findall(L,m(S,L),A),
     length(A,C),
     findall(L,(member(L,A),a(L)),B),
     writeln(C),
     B=[_|_].

En ese caso, el entorno diría 'Sí' o 'No' después de escribir el número de cuadrados.

Ejemplo

Usando eclipse .

[eclipse 105]: p.
 VIIIIVI,IIIVVII,IVIXII
24, true

[eclipse 106]: p.
 IIIXVIII,IVIII,VIIII
210, false

Aquí se pegan resultados de ejemplo para el segundo .


2

Python, 442 caracteres

R=range
L=len
S=sum
N={}
for i in R(40):
 r="";j=i
 while j>9:r+="X";j-=10
 if j>8:r+="IX";j-=9
 if j>4:r+="V";j-=5
 if j>3:r+="IV";j-=4
 N[r+"III"[:j]]=i
a,b,c=map(lambda x:sum([[Z]*all(Z)for i in R(L(x))for j in R(L(x))for Z in[map(N.get,(x[:i],x[i:j],x[j:]))]],[]),raw_input().split(","))
print L(a)*L(b)*L(c),any(S(x)==S(y)==S(z)==S(q[::3])==S(q[1::3])==S(q[2::3])==S(q[::4])==S(q[2:-1:2])for x in a for y in b for z in c for q in[x+y+z])

Primero se crea el código, Nque es una asignación de una cadena de números romanos a su valor para todos los números posibles que podamos necesitar. Divide cada línea en tres de todas las formas posibles y comprueba en cuál de los triples resultantes todos tienen asignaciones N. El final anyve si alguna combinación es un cuadrado mágico.


2

Haskell, 451 429 423 bytes

import Data.List
(#)=splitAt
(%)=map
w=length
r"X"=10
r('X':a)=10+r a
r a=case elemIndex a["I","II","III","IV","V","VI","VII","VIII","IX"]of Just i->i+1;_->0
s l=[r%[a,b,c]|x<-[2..w l],y<-[1..x],let(d,c)=x#l;(a,b)=y#d,r a*r b*r c>0]
e[a,b,c]=a==b&&a==c
p[l,m,n]=[1|a<-l,b<-m,c<-n,e$sum%[a,b,c],e$sum%(transpose[a,b,c])]
f i=(show$product$w%(s%i))++","++(show$0<(w$p$s%i))
q ','='\n'
q a=a
i=getLine>>=putStrLn.f.lines.map q

Uso:

*Main> i                           -- repl prompt, call i
VIIIIVI,IIIVVII,IVIXII             -- input via STDIN    
24,True                            -- output
*Main> i
IIIXVIII,IVIII,VIIII
210,False

Aproximadamente 70 bytes solo para obtener el formato de entrada y salida correcto.

La función rconvierte un número romano (dado como una cadena) en un entero (si no 0se devuelve un número romano válido ). sdivide una cadena de dígitos romanos en 3 subcadenas y mantiene esos triples con números romanos válidos y los convierte ra enteros. ecomprueba si todos los enteros de una lista de tres elementos son iguales. ptoma tres cadenas de dígitos romanos, las divide sen listas de enteros, combina un número entero de cada lista para triplicar y mantiene aquellos con sumas iguales en todas las direcciones. fcalcula el número de matrices válidas y comprueba si pdevuelve la lista vacía (sin solución válida) o no (existe una solución válida). La función principal ilee la entrada de STDIN, la convierte en una lista de cadenas (qayuda reemplazando ,con \n) y llamadas p.


1

R, 489 474 464

Esto se hizo mucho más grande de lo que quería, pero sospecho que puedo jugar un poco más.

Utiliza un método de fuerza bruta, calculando todas las combinaciones posibles de números romanos y sus dígitos correspondientes.

Una vez hecho esto, compara la entrada con la lista de números romanos y obtiene los posibles dígitos.

A partir de ahí, pasa por cada matriz de números y prueba el cuadrado mágico, finalmente genera el resultado.

s=strsplit;e=expand.grid;P=paste0;d=do.call;i=readline();i=s(i,',');n=1:39;r=c(t(outer(c('','X','XX','XXX'),c('I','II','III','IV','V','VI','VII','VIII','IX','X'),P)))[n];p=d(P,e(r,r,r));n=d(paste,e(n,n,n));m=lapply(i[[1]],function(x)which(p==x));C=e(s(n[m[[1]]],' '),s(n[m[[2]]],' '),s(n[m[[3]]],' '));E=F;N=nrow(C);for(n in 1:N){T=matrix(strtoi(unlist(C[n,])),nr=3);E=E||length(unique(c(rowSums(T),colSums(T),sum(diag(T)),sum(diag(T[3:1,])))))==1};P(N,',',any(E))

Prueba de funcionamiento. Espera la entrada una vez pegada en el RGui.

> e=expand.grid;l=length;s=strsplit;P=paste0;i=readline();i=s(i,',');n=1:39;r=c(t(outer(c('','X','XX','XXX'),c('I','II','III','IV','V','VI','VII','VIII','IX','X'),P)))[-40];p=do.call(P,e(r,r,r));n=do.call(paste,e(n,n,n));m=lapply(i[[1]],function(x)which(p==x));C=e(s(n[m[[1]]],' '),s(n[m[[2]]],' '),s(n[m[[3]]],' '));E=c();N=nrow(C);for(n in 1:N){T=matrix(as.integer(unlist(C[n,])),nr=3);E=c(E,length(unique(c(rowSums(T),colSums(T),sum(diag(T)),sum(diag(T[3:1,])))))==1)};paste(N,',',any(E))
VIIIIVI,IIIVVII,IVIXII
[1] "24 , TRUE"
> e=expand.grid;l=length;s=strsplit;P=paste0;i=readline();i=s(i,',');n=1:39;r=c(t(outer(c('','X','XX','XXX'),c('I','II','III','IV','V','VI','VII','VIII','IX','X'),P)))[-40];p=do.call(P,e(r,r,r));n=do.call(paste,e(n,n,n));m=lapply(i[[1]],function(x)which(p==x));C=e(s(n[m[[1]]],' '),s(n[m[[2]]],' '),s(n[m[[3]]],' '));E=c();N=nrow(C);for(n in 1:N){T=matrix(as.integer(unlist(C[n,])),nr=3);E=c(E,length(unique(c(rowSums(T),colSums(T),sum(diag(T)),sum(diag(T[3:1,])))))==1)};paste(N,',',any(E))
IIIXVIII,IVIII,VIIII
[1] "210 , FALSE"
>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.