Mehrdeutige römische Ziffernmagiequadrate


10

Der König des alten Roms hat Schwierigkeiten festzustellen, ob ein magisches Quadrat gültig ist oder nicht, da das magische Quadrat, das er überprüft, keine Trennzeichen zwischen den Zahlen enthält. Er hat einen Softwareentwickler beauftragt, um festzustellen, ob ein magisches Quadrat gültig ist oder nicht.

Eingabebeschreibung

Die Eingabe erfolgt über STDIN- oder Befehlszeilenargumente. Sie können die Eingabe nicht in einer Variablen vorinitialisieren lassen (z. B. "Dieses Programm erwartet die Eingabe in einer Variablen x"). Die Eingabe erfolgt im folgenden Format:

<top>,<middle>,<bottom>

Jede <top>, <middle>und <bottom>ist ein String, wird immer nur die Großbuchstaben enthalten I, Vund X. Es enthält keine Leerzeichen oder andere Zeichen. Jede Zeichenfolge repräsentiert drei römische Ziffern, was zu einer 3x3-Zahlenmatrix führt. Diese römischen Ziffern können jedoch (aber nicht unbedingt) mehrdeutig sein . Lassen Sie mich dies anhand eines Beispiels veranschaulichen. Betrachten Sie die folgende Beispielzeile mit drei römischen Ziffern ohne Leerzeichen zwischen den einzelnen Ziffern:

IVIIIIX

Da zwischen den Buchstaben keine Leerzeichen stehen, gibt es hier zwei Möglichkeiten für die Zahlen:

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

Wenn Sie bedenken, dass alle drei Zeilen der Matrix mehrdeutig sein können, besteht die Möglichkeit, dass eine einzelne Eingabe viele verschiedene 3x3-Matrizen enthält.

Beachten Sie, dass Sequenzen wie 1, 7, 1, 9 ( I VII I IX) nicht möglich sind, da jede Zeile immer drei römische Ziffern darstellt. Beachten Sie auch, dass die römischen Ziffern gültig sein müssen, sodass auch Sequenzen wie 1, 7, 8 ( I VII IIX) nicht möglich sind.

Beschreibung der Ausgabe

Ausgabe:

  • Eine Ganzzahl A, wobei Adie Anzahl der eindeutigen 3x3-Matrizen ist, die aus der mehrdeutigen Eingabe gebildet werden können, und:
  • Ein wahrer Wert, wenn eine der einzigartigen 3x3-Matrizen ein magisches Quadrat bildet, oder:
  • Ein falscher Wert, wenn keine der eindeutigen 3x3-Matrizen ein magisches Quadrat bildet.

Die Wahrheits- und Falschwerte müssen konsistent sein. Sie werden durch ein Komma getrennt.

Es ist eine Erklärung erforderlich, was als eindeutig gezählt wird. Solange eine Matrix nicht genau die gleichen Zahlen an genau den gleichen Positionen wie eine zuvor gefundene Matrix hat, wird sie als eindeutig gezählt. Dies bedeutet, dass Reflexionen usw. von zuvor gefundenen Matrizen als eindeutig gezählt werden.

Beispiel für Ein- und Ausgänge

In diesen Beispielen verwende ich trueals meinen Wahrheitswert und falseals meinen Falschwert.

Eingabe: VIIIIVI,IIIVVII,IVIXII Ausgabe: 24,true (Das magische Dreieck ist 8-1-6, 3-5-7, 4-9-2.)

Eingabe: IIIXVIII,IVIII,VIIII Ausgabe:210,false

Extras

  • Sie dürfen keine integrierten Konvertierungsfunktionen für römische Zahlen verwenden, wenn Ihre ausgewählte Sprache eine hat.

"König des alten Roms" ... Kaiser?
Digitales Trauma

8
@DigitalTrauma Es spielt in einem alternativen Universum, in dem das antike Rom einen König, magische Quadrate und Software-Ingenieure hatte. Oder so ähnlich ...
Absinth

Außerdem sollten Sie einen Interpunct (·) anstelle eines Kommas verwenden ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump

Ich habe "24, wahr" für das erste, aber "210, falsch" für das zweite Beispiel. Ich werde nachforschen.
Coredump

1
@ DigitalTrauma Rom hatte Könige bis etwa 509 v.
Jon B

Antworten:


4

Perl, 219 237

Zeilenumbrüche wurden aus Gründen der Übersichtlichkeit hinzugefügt.

#!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 mich .


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

Natürlich pkönnte auch definiert werden als:

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 diesem Fall würde die Umgebung nach dem Schreiben der Anzahl der Quadrate "Ja" oder "Nein" sagen.

Beispiel

Mit Eclipse .

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

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

Beispielergebnisse für das zweite werden hier eingefügt .


2

Python, 442 Zeichen

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

Der Code wird zuerst erstellt. Dabei Nhandelt es sich um eine Zuordnung von einer römischen Zeichenfolge zu ihrem Wert für alle möglichen Zahlen, die wir möglicherweise benötigen. Teilt jede Zeile auf jede mögliche Weise in drei Zeilen und überprüft, in welchem ​​der resultierenden Tripel alle Zuordnungen enthalten sind N. Das Finale anysieht, ob eine Kombination ein magisches Quadrat ist.


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

Verwendungszweck:

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

Etwa 70 Bytes, nur um das Eingabe- und Ausgabeformat richtig zu machen.

Die Funktion rkonvertiert eine römische Zahl (als Zeichenfolge angegeben) in eine Ganzzahl (wenn keine gültige römische Zahl 0zurückgegeben wird). steilt eine Folge von römischen Ziffern in 3 Teilzeichenfolgen auf und behält diese Tripel mit gültigen römischen Zahlen bei und konvertiert sie über rin ganze Zahlen. eprüft, ob alle ganzen Zahlen einer Liste mit drei Elementen gleich sind. pNimmt drei Zeichenfolgen römischer Ziffern, teilt sie sin Ganzzahllisten auf, kombiniert eine Ganzzahl jeder Liste zu Dreiergruppen und behält diese mit gleichen Summen in alle Richtungen bei. fberechnet die Anzahl der gültigen Matrizen und prüft, ob pdie leere Liste zurückgegeben wird (keine gültige Lösung) oder nicht (gültige Lösung vorhanden). Die Hauptfunktion iliest die Eingabe von STDIN und konvertiert sie in eine Liste von Zeichenfolgen (qhilft durch Ersetzen ,durch \n) und Anrufe p.


1

R, 489 474 464

Das wurde viel größer als ich wollte, aber ich vermute, ich kann es ein bisschen Golf spielen.

Es verwendet eine Brute-Force-Methode, indem alle möglichen Kombinationen der römischen Ziffern und ihre entsprechenden Ziffern berechnet werden.

Sobald dies erledigt ist, vergleicht es die Eingabe mit der Liste der römischen Zahlen und erhält die möglichen Ziffern.

Von dort geht es durch jede Zahlenmatrix und testet auf das magische Quadrat, um schließlich das Ergebnis auszugeben.

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

Testlauf. Es wartet auf Eingaben, die in das RGui eingefügt wurden.

> 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"
>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.