Ambiguous Roman Numeral Magic Squares

10

Raja Roma Kuno mengalami kesulitan menentukan apakah kotak ajaib itu valid atau tidak, karena kotak ajaib yang dia periksa tidak termasuk pemisah di antara angka-angkanya. Dia telah menyewa seorang insinyur perangkat lunak untuk membantunya menentukan apakah kotak ajaib itu valid atau tidak.

Deskripsi Input

Input masuk pada argumen STDIN atau baris perintah. Anda tidak dapat memiliki input yang diinisialisasi dalam variabel (mis. "Program ini mengharapkan input dalam variabel x"). Input dalam format berikut:

<top>,<middle>,<bottom>

Masing-masing <top>, <middle>dan <bottom>merupakan string yang akan hanya pernah berisi karakter huruf besar I, Vdan X. Itu tidak akan berisi spasi atau karakter lain. Setiap string mewakili tiga angka Romawi, sehingga menghasilkan matriks angka 3x3. Namun, angka-angka Romawi ini mungkin (tetapi tidak harus) ambigu . Izinkan saya menggambarkan ini dengan sebuah contoh. Pertimbangkan contoh baris berikut dari tiga angka Romawi, tanpa spasi di antara setiap angka:

IVIIIIX

Karena tidak ada spasi di antara huruf-huruf, ada dua kemungkinan nomor di sini:

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

Ketika Anda menganggap bahwa ketiga baris matriks dapat bersifat ambivalen, ada potensi untuk ada banyak matriks 3x3 berbeda dari satu input.

Perhatikan bahwa urutan seperti 1, 7, 1, 9 ( I VII I IX) tidak dimungkinkan karena setiap baris akan selalu mewakili tiga angka Romawi. Perhatikan juga bahwa angka Romawi harus valid, sehingga urutan seperti 1, 7, 8 ( I VII IIX) juga tidak mungkin.

Deskripsi Output

Keluaran:

  • Bilangan bulat A, di mana Ajumlah matriks 3x3 unik yang dapat dibentuk dari input yang ambisius, dan:
  • Nilai kebenaran jika salah satu dari matriks 3x3 unik membentuk kotak ajaib, atau:
  • Nilai palsu jika tidak ada matriks 3x3 unik yang membentuk kotak ajaib.

Nilai kebenaran dan kepalsuan harus konsisten. Mereka dipisahkan oleh koma.

Diperlukan beberapa penjelasan tentang apa yang dianggap unik. Selama sebuah matriks tidak memiliki angka yang persis sama dalam posisi yang sama persis dengan matriks yang ditemukan sebelumnya, ia dihitung sebagai unik. Ini berarti bahwa refleksi, dll. Dari matriks yang ditemukan sebelumnya dihitung sebagai unik.

Contoh Input dan Output

Dalam contoh-contoh ini, saya gunakan truesebagai nilai kebenaran saya dan falsesebagai nilai palsu saya.

Input: VIIIIVI,IIIVVII,IVIXII Output: 24,true (Segitiga ajaib adalah 8-1-6, 3-5-7, 4-9-2.)

Input: IIIXVIII,IVIII,VIIII Keluaran:210,false

Ekstra

  • Anda tidak diperbolehkan menggunakan fungsi konversi Angka Romawi bawaan jika bahasa pilihan Anda memilikinya.
Absinth
sumber
"raja Roma Kuno" ... Kaisar?
Digital Trauma
8
@DigitalTrauma Terletak di alam semesta alternatif di mana Roma Kuno memiliki seorang raja, kotak ajaib, dan insinyur perangkat lunak. Atau sesuatu seperti itu ...
absinth
Selain itu, Anda harus menggunakan interpunct (·) alih-alih koma ( en.wikipedia.org/wiki/Interpunct#Latin )
coredump
Saya memiliki "24, benar" untuk yang pertama, tetapi "210, salah" untuk contoh kedua. Saya akan selidiki.
coredump
1
@DigitalTrauma Roma memiliki raja sampai sekitar 509BC.
Jon B

Jawaban:

4

Perl, 219 237

Jeda baris ditambahkan untuk kejelasan.

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

Ujilah aku .

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

Tidak disatukan

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

Tentu saja, pdapat juga didefinisikan sebagai:

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

Dalam hal ini, lingkungan akan mengatakan 'Ya' atau 'Tidak' setelah menulis jumlah kotak.

Contoh

Menggunakan gerhana .

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

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

Contoh hasil untuk yang kedua ditempelkan di sini .

coredump
sumber
2

Python, 442 karakter

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

Kode pertama kali dibuat Nyang merupakan pemetaan dari string angka romawi ke nilainya untuk semua angka yang mungkin kita butuhkan. Pisahkan setiap baris menjadi tiga dengan segala cara yang mungkin dan periksa yang mana dari triples yang dihasilkan semuanya memiliki pemetaan N. Final anymelihat apakah kombinasi adalah kotak ajaib.

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

Pemakaian:

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

Sekitar 70 byte hanya untuk mendapatkan format input dan output yang benar.

Fungsi rmengubah angka romawi (diberikan sebagai string) ke integer (jika bukan angka romawi 0yang dikembalikan). smembagi string angka romawi menjadi 3 substring dan membuat triples tersebut dengan angka romawi yang valid dan mengubahnya melalui rbilangan bulat. ememeriksa apakah semua bilangan bulat dari daftar tiga elemen sama. pmengambil tiga string angka romawi, membaginya melalui sdaftar bilangan bulat, menggabungkan satu bilangan bulat dari setiap daftar menjadi tiga kali lipat dan menyimpannya dengan jumlah yang sama di semua arah. fmenghitung jumlah matriks yang valid dan memeriksa apakah pmengembalikan daftar kosong (tidak ada solusi yang valid) atau tidak (ada solusi yang valid). Fungsi utama imembaca input dari STDIN, mengubahnya menjadi daftar string (qmembantu dengan mengganti ,dengan \n) dan panggilan p.

nimi
sumber
1

R, 489 474 464

Ini menjadi jauh lebih besar dari yang saya inginkan, tetapi saya curiga saya bisa menurunkannya sedikit.

Ini menggunakan metode brute force, dengan menghitung semua kemungkinan kombinasi Angka Romawi dan angka yang sesuai.

Setelah itu selesai membandingkan input ke daftar Angka Romawi dan mendapatkan kemungkinan digit.

Dari sana ia melewati setiap matriks angka dan menguji untuk kotak ajaib, akhirnya menghasilkan hasilnya.

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

Uji Coba. Ia menunggu input yang pernah disisipkan ke dalam 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
sumber