あいまいなローマ数字の魔方陣


10

古代ローマの王は、魔方陣が有効かどうかを判断するのに苦労しています。彼がチェックしている魔方陣には、数字の間にセパレータが含まれていないためです。彼はソフトウェアエンジニアを雇って、魔法陣が有効かどうかを判断する手助けをしました。

入力の説明

入力はSTDINまたはコマンドライン引数で受け取ります。変数で入力を事前に初期化することはできません(たとえば、「このプログラムは変数への入力を想定していますx」)。入力は次の形式です。

<top>,<middle>,<bottom>

それぞれ<top><middle>、と<bottom>しか大文字の文字を含む文字列ですIVX。スペースやその他の文字は含まれません。各文字列は3つのローマ数字を表すため、3x3の数値行列になります。ただし、これらのローマ数字はあいまいである可能性があります(ただし、そうである必要はありません)。これを例を使って説明します。次の3つのローマ数字の行の例を考えてみます。各数字の間にスペースはありません。

IVIIIIX

文字の間にスペースがないため、ここの数字には2つの可能性があります。

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

マトリックスの3行すべてが不明確である可能性があると考える場合、単一の入力から多くの異なる3x3マトリックスが存在する可能性があります。

I VII I IX各行は常に3つのローマ数字を表すため、1、7、1、9()などのシーケンスは使用できないことに注意してください。また、ローマ数字は有効でなければならないため、1、7、8(I VII IIX)などのシーケンスも使用できないことに注意してください。

出力の説明

出力:

  • 整数A。ここでA、あいまいな入力から形成できる一意の3x3行列の数。
  • ユニークな3x3マトリックスのいずれかが魔方陣を形成する場合の真実値、または:
  • falsy値ならばどれもユニークな3×3の行列のは、魔方陣を形成していません。

真実で偽りの値は一貫している必要があります。それらはコンマで区切られます。

ユニークと見なされるものについて、いくつかの説明が必要です。マトリックスが以前に見つかったマトリックスと正確に同じ位置に正確に同じ数を持たない限り、それは一意としてカウントされます。これは、以前に見つかったマトリックスの反射などが一意としてカウントされることを意味します。

入力と出力の例

これらの例では、私はtrue私の真実の値と私の偽りの値として使用していfalseます。

入力:VIIIIVI,IIIVVII,IVIXII 出力:(24,true 魔法の三角形は8-1-6、3-5-7、4-9-2です。)

入力:IIIXVIII,IVIII,VIIII 出力:210,false

エクストラ

  • 選択した言語に含まれている場合、組み込みのローマ数字変換関数を使用することはできません。

「古代ローマの王様」 …天皇?
Digital Trauma 2015年

8
@DigitalTraumaこれは、古代ローマに王、魔方陣、ソフトウェアエンジニアがいた別の世界に設定されています。または、そのようなもの
2015年

また、コンマ(en.wikipedia.org/wiki/Interpunct#Latin)ではなくinterpunct(・)を使用する必要があります
コアダンプ

最初の例は「24、true」ですが、2番目の例は「210、false」です。調査します。
コアダンプ2015年

1
@DigitalTraumaローマには、紀元前509年頃まで王がいました。
ジョンB

回答:


4

Perl、219 237

明確にするために改行が追加されました。

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

私をテストしてください


4

プロローグ-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)).

未ゴルフ

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

もちろん、次のpように定義することもできます。

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

その場合、正方形の数を書き込んだ後、環境は「はい」または「いいえ」と表示します。

日食を使用します。

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

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

2番目の例の結果はここに貼り付けられます


2

Python、442文字

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

コードは最初に構築されます。Nこれは、ローマ数字の文字列から、必要になる可能性のあるすべての数値の値へのマッピングです。すべての可能な方法で各行を3つに分割し、結果のトリプルのどれがにマッピングされているかをチェックしNます。決勝戦anyは、いずれかの組み合わせが魔方陣であるかどうかを確認します。


2

Haskell、451 429 423バイト

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

使用法:

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

入力と出力のフォーマットを正しくするためだけに約70バイト。

この関数はr、ローマ数字(文字列として指定)を整数に変換します(有効なローマ数字0が返されない場合)。sローマ数字の文字列を3つの部分文字列に分割し、それらのトリプルを有効なローマ数字で保持し、それらrを整数に変換します。e3つの要素のリストのすべての整数が等しいかどうかをチェックします。pローマ数字の3つの文字列を取り、それらをs整数のリストに分割し、各リストの1つの整数を3つに結合し、それらをすべての方向で等しい合計で保持します。f有効な行列の数を計算しp、空のリストが返されるか(有効な解がない)か返されないか(有効な解が存在するか)をチェックします。メイン関数iはSTDINから入力を読み取り、それを文字列のリストに変換します(q)と呼び出しで置き換えること,で役立ち\nますp


1

R、489 474 464

これは私が思ったよりもずっと大きくなりましたが、私はそれを少し下にゴルフすることができると思います。

それはすべての可能なローマ数字の組み合わせとそれらに対応する数字を計算することにより、総当たり法を使用します。

それが完了すると、入力をローマ数字のリストと比較し、可能な数字を取得します。

そこから、数値の各行列を調べ、魔方陣をテストし、最終的に結果を出力します。

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

テスト走行。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"
>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.