Niejednoznaczne magiczne kwadraty z rzymską liczbą

10

Król starożytnego Rzymu ma trudności z ustaleniem, czy magiczny kwadrat jest prawidłowy, czy nie, ponieważ magiczny kwadrat, który sprawdza, nie zawiera żadnych separatorów między liczbami. Zatrudnił inżyniera oprogramowania, który pomoże mu ustalić, czy magiczny kwadrat jest prawidłowy, czy nie.

Opis wejścia

Dane wejściowe pochodzą z argumentów STDIN lub wiersza poleceń. Nie można wstępnie zainicjować danych wejściowych w zmiennej (np. „Ten program oczekuje danych wejściowych w zmiennej x”). Dane wejściowe mają następujący format:

<top>,<middle>,<bottom>

Każdy z <top>, <middle>i <bottom>to ciąg znaków, który będzie zawsze tylko zawierać duże litery I, Vi X. Nie będzie zawierać spacji ani żadnych innych znaków. Każdy ciąg reprezentuje trzy cyfry rzymskie, w wyniku czego powstaje macierz liczb 3x3. Jednak te cyfry rzymskie mogą (ale niekoniecznie) być niejednoznaczne . Pozwól, że zilustruję to przykładem. Rozważ następujący przykładowy rząd trzech cyfr rzymskich, bez spacji między każdą liczbą:

IVIIIIX

Ponieważ między literami nie ma spacji, cyfry mają dwie możliwości:

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

Gdy weźmiesz pod uwagę, że wszystkie trzy wiersze macierzy mogą być niejednoznaczne, istnieje możliwość, że z jednego wejścia będzie wiele różnych matryc 3x3.

Zauważ, że sekwencje takie jak 1, 7, 1, 9 ( I VII I IX) nie są możliwe, ponieważ każdy wiersz zawsze będzie reprezentował trzy cyfry rzymskie. Zauważ też, że cyfry rzymskie muszą być poprawne, więc sekwencje takie jak 1, 7, 8 ( I VII IIX) również nie są możliwe.

Opis wyjścia

Wynik:

  • Liczba całkowita A, gdzie Ajest liczba unikalnych macierzy 3x3, które można utworzyć z niejednoznacznych danych wejściowych, oraz:
  • Truthy wartość, jeśli każdy z unikalnych matryc 3x3 tworzą magiczny kwadrat, lub:
  • Falsy wartość, jeżeli żaden z unikalnych matryc 3x3 tworzą magiczny kwadrat.

Wartości prawdy i fałszu muszą być spójne. Są oddzielone przecinkiem.

Wymagane jest wyjaśnienie tego, co jest uważane za unikalne. Dopóki macierz nie ma dokładnie takich samych liczb w dokładnie takich samych pozycjach jak poprzednio znaleziona macierz, jest liczona jako unikalna. Oznacza to, że odbicia itp. Wcześniej znalezionych matryc są liczone jako unikalne.

Przykładowe wejścia i wyjścia

W tych przykładach używam truejako mojej prawdziwej wartości i falsemojej wartości fałszowania.

Wejście: VIIIIVI,IIIVVII,IVIXII Wyjście: 24,true (Magiczny trójkąt to 8-1-6, 3-5-7, 4-9-2.)

Wejście: IIIXVIII,IVIII,VIIII Wyjście:210,false

Dodatki

  • Nie możesz korzystać z wbudowanych funkcji konwersji cyframi rzymskimi, jeśli masz wybrany język.
Absynt
źródło
„król starożytnego Rzymu” ... cesarz?
Cyfrowy uraz
8
@DigitalTrauma Akcja gry osadzona jest w alternatywnym wszechświecie, w którym starożytny Rzym miał króla, magiczne kwadraty i inżynierów oprogramowania. Lub coś takiego ...
absynt
Powinieneś także użyć interpunktu (·) zamiast przecinka ( en.wikipedia.org/wiki/Interpunct#Latin )
rdzeń
Mam „24, prawda” dla pierwszego, ale „210, fałsz” dla drugiego przykładu. Zbadam.
coredump
1
@DigitalTrauma Rzym miał królów do około 509 pne.
Jon B

Odpowiedzi:

4

Perl, 219 237

Dodano podział linii dla zachowania przejrzystości.

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

Przetestuj mnie .

nutki
źródło
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)).

Nie golfił

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

Oczywiście pmożna to również zdefiniować jako:

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

W takim przypadku środowisko powie „Tak” lub „Nie” po zapisaniu liczby kwadratów.

Przykład

Korzystanie z zaćmienia .

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

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

Przykładowe wyniki dla drugiego są wklejone tutaj .

rdzeń rdzeniowy
źródło
2

Python, 442 znaki

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

Najpierw buduje się kod, Nktóry jest odwzorowaniem ciągu cyfr rzymskich na jego wartość dla wszystkich możliwych liczb, których możemy potrzebować. Dzieli każdą linię na trzy w każdy możliwy sposób i sprawdza, w których z wszystkich trzech potęg ma wszystkie odwzorowania N. Finał anysprawdza, czy jakakolwiek kombinacja jest magicznym kwadratem.

Keith Randall
źródło
2

Haskell, 451 429 423 bajtów

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

Stosowanie:

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

Około 70 bajtów tylko po to, aby uzyskać właściwy format wejściowy i wyjściowy.

Funkcja rkonwertuje liczbę rzymską (podaną jako ciąg znaków) na liczbę całkowitą (jeśli nie 0jest zwracana poprawna liczba rzymska ). sdzieli ciąg cyfr rzymskich na 3 podłańcuchy i zachowuje te trzykrotnie z prawidłowymi liczbami rzymskimi i konwertuje je rna liczby całkowite. esprawdza, czy wszystkie liczby całkowite z listy trzech elementów są równe. ppobiera trzy ciągi cyfr rzymskich, dzieli je sna listy liczb całkowitych, łączy jedną liczbę całkowitą z każdej listy w trzykrotnie i utrzymuje je z jednakowymi sumami we wszystkich kierunkach. foblicza liczbę prawidłowych macierzy i sprawdza, czy pzwraca pustą listę (brak poprawnego rozwiązania), czy nie (poprawne rozwiązanie istnieje). Główna funkcja iodczytuje dane wejściowe ze STDIN, konwertuje je na listę ciągów (qPomaga zastępując ,z \n) i rozmowy p.

nimi
źródło
1

R, 489 474 464

To stało się znacznie większe, niż chciałem, ale podejrzewam, że mogę trochę pograć w golfa.

Wykorzystuje metodę brutalnej siły, obliczając wszystkie możliwe kombinacje cyfr rzymskich i odpowiadające im cyfry.

Po zakończeniu porównuje dane wejściowe z listą cyfr rzymskich i otrzymuje możliwe cyfry.

Następnie przechodzi przez każdą macierz liczb i testuje magiczny kwadrat, w końcu generując wynik.

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

Testowe uruchomienie. Po wklejeniu do RGui czeka na dane wejściowe.

> 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
źródło