Quadrados Mágicos de Números Romanos Ambíguos

10

O rei da Roma antiga está tendo dificuldades para determinar se um quadrado mágico é válido ou não, porque o quadrado mágico que ele está verificando não inclui separadores entre os números. Ele contratou um engenheiro de software para ajudá-lo a determinar se um quadrado mágico é válido ou não.

Descrição da entrada

A entrada é apresentada em argumentos STDIN ou de linha de comando. Você não pode ter a entrada pré-inicializada em uma variável (por exemplo, "este programa espera a entrada em uma variável x"). A entrada está no seguinte formato:

<top>,<middle>,<bottom>

Cada um <top>, <middle>e <bottom>é uma string que só vai conter os caracteres maiúsculos I, Ve X. Não conterá espaços ou outros caracteres. Cada string representa três algarismos romanos, resultando em uma matriz de números 3x3. No entanto, esses números romanos podem (mas não necessariamente) ser ambíguos . Permita-me ilustrar isso com um exemplo. Considere o exemplo de linha a seguir de três algarismos romanos, sem espaços entre cada número:

IVIIIIX

Como não há espaços entre as letras, existem duas possibilidades para os números aqui:

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

Quando você considera que todas as três linhas da matriz podem ser ambíguas, existe o potencial de haver muitas matrizes 3x3 diferentes a partir de uma única entrada.

Observe que seqüências como 1, 7, 1, 9 ( I VII I IX) não são possíveis porque cada linha sempre representa três números romanos. Observe também que os números romanos devem ser válidos, portanto, seqüências como 1, 7, 8 ( I VII IIX) também não são possíveis.

Descrição da saída

Resultado:

  • Um número inteiro A, onde Aé o número de matrizes 3x3 exclusivas que podem ser formadas a partir da entrada ambígua e:
  • Um valor verdadeiro se alguma das matrizes 3x3 únicas formar um quadrado mágico ou:
  • Um valor falso se nenhuma das matrizes 3x3 únicas formar um quadrado mágico.

Os valores de verdade e falsidade devem ser consistentes. Eles são separados por uma vírgula.

Alguma explicação é necessária sobre o que é contado como único. Desde que uma matriz não tenha exatamente os mesmos números nas mesmas posições que uma matriz encontrada anteriormente, ela será contada como única. Isso significa que as reflexões etc. das matrizes encontradas anteriormente são contadas como únicas.

Exemplo de entradas e saídas

Nestes exemplos, eu uso truecomo meu valor de falseverdade e como meu valor de falsidade.

Entrada: VIIIIVI,IIIVVII,IVIXII Saída: 24,true (O triângulo mágico é 8-1-6, 3-5-7, 4-9-2.)

Entrada: IIIXVIII,IVIII,VIIII Saída:210,false

Extras

  • Você não tem permissão para usar funções de conversão incorporadas de números romanos se o idioma escolhido tiver um.
absinto
fonte
"rei da Roma antiga" ... Imperador?
Digital Trauma
8
@DigitalTrauma É ambientado em um universo alternativo, onde a Roma Antiga tinha um rei, quadrados mágicos e engenheiros de software. Ou algo assim ...
absinto
Além disso, você deve usar um interpunct (·) em vez de uma vírgula ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump
Eu tenho "24, verdadeiro" para o primeiro, mas "210, falso" para o segundo exemplo. Eu investigarei.
Coredump
11
@DigitalTrauma Rome teve reis até cerca de 509 aC.
Jon B

Respostas:

4

Perl, 219 237

Quebras de linha adicionadas para maior clareza.

#!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"

Teste- me .

nutki
fonte
4

Prolog - 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)).

Ungolfed

% 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)).

Obviamente, ptambém pode ser definido 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=[_|_].

Nesse caso, o ambiente diria 'Sim' ou 'Não' depois de escrever o número de quadrados.

Exemplo

Usando eclipse .

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

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

Resultados de exemplo para o segundo são colados aqui .

coredump
fonte
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])

O código primeiro cria Num mapeamento da sequência do número romano para o seu valor para todos os números possíveis que precisarmos. Divide cada linha em três de todas as maneiras possíveis e verifica em qual dos triplos resultantes todos têm mapeamentos N. A final anyvê se alguma combinação é um quadrado mágico.

Keith Randall
fonte
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

Cerca de 70 bytes apenas para obter o formato de entrada e saída correto.

A função rconverte um número romano (fornecido como uma string) em um número inteiro (se não 0for retornado um número romano válido ). sdivide uma sequência de dígitos romanos em 3 substring e mantém esses triplos com números romanos válidos e os converte rem inteiros. everifica se todos os números inteiros de uma lista de três elementos são iguais. ppega três strings de dígitos romanos, divide-os sem listas de números inteiros, combina um número inteiro de cada lista em triplos e mantém aqueles com somas iguais em todas as direções. fcalcula o número de matrizes válidas e verifica se pretorna a lista vazia (nenhuma solução válida) ou não (existe uma solução válida). A função principal ilê a entrada de STDIN, converte-a em uma lista de strings (qajuda substituindo ,por \n) e chamadas p.

nimi
fonte
1

R, 489 474 464

Isso ficou muito maior do que eu queria, mas suspeito que posso jogar um pouco.

Ele usa um método de força bruta, calculando todas as combinações possíveis de números romanos e seus dígitos correspondentes.

Feito isso, ele compara a entrada com a lista de números romanos e obtém os dígitos possíveis.

A partir daí, ele passa por cada matriz de números e testa o quadrado mágico, finalmente produzindo o 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))

Execução de teste. Aguarda a entrada uma vez colada no 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"
>
MickyT
fonte