Ambigui quadrati magici numerali romani


10

Il re dell'antica Roma ha difficoltà a determinare se un quadrato magico è valido o meno, perché il quadrato magico che sta controllando non include alcun separatore tra i numeri. Ha assunto un ingegnere informatico per aiutarlo a determinare se un quadrato magico è valido o meno.

Descrizione dell'input

L'input arriva su STDIN o argomenti della riga di comando. Non è possibile pre-inizializzare l'ingresso in una variabile (ad es. "Questo programma prevede l'ingresso in una variabile x"). L'input è nel seguente formato:

<top>,<middle>,<bottom>

Ognuno di <top>, <middle>ed <bottom>è una stringa che sarà sempre e solo contenere i caratteri maiuscoli I, Ve X. Non conterrà spazi o altri caratteri. Ogni stringa rappresenta tre numeri romani, risultando in una matrice di numeri 3x3. Tuttavia, questi numeri romani possono (ma non necessariamente) essere ambigui . Mi permetta di illustrare questo con un esempio. Considera la seguente riga di esempio di tre numeri romani, senza spazi tra ogni numero:

IVIIIIX

Poiché non ci sono spazi tra le lettere, ci sono due possibilità per i numeri qui:

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

Se si considera che tutte e tre le righe della matrice possono essere ambigue, esiste la possibilità che ci siano molte matrici 3x3 diverse da un singolo input.

Notare che sequenze come 1, 7, 1, 9 ( I VII I IX) non sono possibili perché ogni riga rappresenterà sempre tre numeri romani. Si noti inoltre che i numeri romani devono essere validi, quindi non sono possibili sequenze come 1, 7, 8 ( I VII IIX).

Descrizione dell'uscita

Produzione:

  • Un numero intero A, dove Aè il numero di matrici 3x3 uniche che possono essere formate dall'input ambiguo, e:
  • Un valore veritiero se una qualsiasi delle matrici 3x3 uniche forma un quadrato magico o:
  • Un valore falso se nessuna delle uniche matrici 3x3 formano un quadrato magico.

I valori di verità e falsità devono essere coerenti. Sono separati da una virgola.

Sono necessarie alcune spiegazioni su ciò che viene considerato unico. Fintanto che una matrice non ha esattamente gli stessi numeri esattamente nelle stesse posizioni di una matrice trovata in precedenza, viene considerata unica. Ciò significa che le riflessioni, ecc. Delle matrici trovate in precedenza vengono considerate uniche.

Ingressi e uscite di esempio

In questi esempi, utilizzo truecome valore di verità e falsevalore di falsità.

Input: VIIIIVI,IIIVVII,IVIXII Output: 24,true (Il triangolo magico è 8-1-6, 3-5-7, 4-9-2.)

Ingresso: IIIXVIII,IVIII,VIIII Uscita:210,false

extra

  • Non è consentito utilizzare le funzioni integrate di conversione del numero romano se la lingua scelta ne possiede una.

"re dell'antica Roma" ... imperatore?
Trauma digitale

8
@DigitalTrauma È ambientato in un universo alternativo in cui l'antica Roma aveva un re, quadrati magici e ingegneri del software. O qualcosa del genere ...
assenzio

Inoltre, dovresti usare un interpunct (·) invece di una virgola ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump

Ho "24, true" per il primo, ma "210, false" per il secondo esempio. Investigherò.
coredump

1
@DigitalTrauma Rome ebbe re fino al 509 a.C. circa.
Jon B

Risposte:


4

Perl, 219 237

Le interruzioni di riga sono state aggiunte per maggiore chiarezza.

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

Metti alla prova me .


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

Naturalmente, ppotrebbe anche essere definito come:

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

In tal caso, l'ambiente direbbe "Sì" o "No" dopo aver scritto il numero di quadrati.

Esempio

Usando l' eclissi .

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

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

I risultati di esempio per il secondo sono incollati qui .


2

Python, 442 caratteri

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

Il codice crea innanzitutto Nuna mappatura dalla stringa numerica romana al suo valore per tutti i possibili numeri di cui potremmo avere bisogno. Divide ogni riga in tre in ogni modo possibile e controlla in quali delle triple risultanti sono presenti delle mappature N. La finale anyvede se una combinazione è un quadrato magico.


2

Haskell, 451 429 423 byte

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

Circa 70 byte solo per ottenere il formato di input e output corretto.

La funzione rconverte un numero romano (dato come una stringa) in un numero intero (se non 0viene restituito un numero romano valido ). sdivide una stringa di cifre romane in 3 sottostringhe e mantiene quelle triple con numeri romani validi e le converte rin numeri interi. econtrolla se tutti i numeri interi di un elenco di tre elementi sono uguali. pprende tre stringhe di cifre romane, le divide sin liste di numeri interi, combina un numero intero di ciascuna lista per triplicare e mantiene quelle con somme uguali in tutte le direzioni. fcalcola il numero di matrici valide e verifica se prestituisce l'elenco vuoto (nessuna soluzione valida) o meno (esiste una soluzione valida). La funzione principale ilegge l'input da STDIN, lo converte in un elenco di stringhe (qaiuta sostituendo ,con \n) e chiama p.


1

R, 489 474 464

Questo è diventato molto più grande di quello che volevo, ma sospetto di poterlo giocare un po '.

Utilizza un metodo di forza bruta, calcolando tutte le possibili combinazioni di numeri romani e le cifre corrispondenti.

Fatto ciò, confronta l'input con l'elenco dei numeri romani e ottiene le cifre possibili.

Da lì passa attraverso ogni matrice di numeri e verifica il quadrato magico, producendo infine il risultato.

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

Prova. Attende l'input una volta incollato nell'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"
>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.