アリストテレスの数問題を解く


21

アリストテレスの数値パズルは、各軸に沿った合計が38になるように、1〜19の一意の整数を使用して、六角形グリッドの19個のセルのそれぞれにデータを取り込むという課題です。

ゲームボードは次のように描くことができます。

アリストテレスグリッド

パズルは、本質的に、次の15の方程式のセットの解決策です。

((a + b + c) == 38 && (d + e + f + g) == 38 && (h + i + j + k + l) == 
   38 && (m + n + o + p) == 38 && (q + r + s) == 38 && (a + d + h) == 
   38 && (b + e + i + m) == 38 && (c + f + j + n + q) == 
   38 && (g + k + o + r) == 38 && (l + p + s) == 38 && (c + g + l) == 
   38 && (b + f + k + p) == 38 && (a + e + j + o + s) == 
   38 && (d + i + n + r) == 38 && (h + m + q) == 38)

各変数は、セット内の一意の番号{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}です。

考えられる解決策は複数あり19!、整数の可能な組み合わせであるため、単純なブルートフォースは実用的ではありません。

ルール:

  1. 答えをハードコーディングしたり、他の場所で答えを調べたりすることはありません。あなたのコードは自分でそれを見つける必要があります
  2. 速度は重要ではありませんが、結果を表示する必要があるため、実行に1000年かかるコードは役に立ちません
  3. すべての答えを見つける
  4. ローテーションで同一の回答を同一として扱う
  5. 魅力的なハニカムで結果を出力する場合、合計バイト数の5%を差し引く
  6. 最少バイト数が勝つ

素晴らしい質問です。それに対する解決策を検討することを楽しみにしています。
プログラマー14年

ローテーションされた回答を一意とみなしますか?たとえば、a、b、c = 1、18、19が特定のソリューションにインデックスを付け、c、g、lを1、18、19に設定し、他のすべての値が一致するように「回転」すると仮定します。溶液?
プログラマー14年

@ProgrammerDan回転された回答は同じです。明確にします。
マイケルスターン14年

1
六角形には、単なる回転以上の対称性があります。ローテーションとリフレクションの組み合わせで同一の回答はどうですか?
ピーターテイラー14年

自己組織化マップを使用して、これに対する解決策を見ることに興味があります。
アリP

回答:


3

ハスケル295 289

import Data.List
t=38
y a b=[max(19-b)(a+1)..19]
w=y 0 t
x=filter((==w).sort)$[[a,b,c,d,e,f,g,h,i,t-a-e-o-s,k,l,m,t-d-i-r,o,p,q,r,s]|a<-[1..14],c<-y a a,l<-y a c,s<-y a l,q<-y a s,h<-y c q,e<-w,let{f=t-g-e-d;i=t-b-e-m;o=t-r-k-g;k=t-p-f-b;b=t-a-c;g=t-l-c;p=t-l-s;r=t-q-s;m=t-q-h;d=t-a-h}]

算術を使用して中間ヘクスを取得する別の同様の答え。他のソリューションとは異なり、これらの合計が0より大きいかどうかはテストしません。ソートされたヘックスが範囲[1..19]に等しいことをテストするだけで十分です。a、c、およびhは制限されているため、一意に回転/ミラー化されたソリューションのみが許可されます。数秒後に解決策が表示され、それ以上はないと判断するまで1分ほど待機します。

ghciでの使用:

ghci> x
[[3,19,16,17,7,2,12,18,1,5,4,10,11,6,8,13,9,14,15]]

いくつかの文字を剃るように編集されました。'y 0 t'は[1..19]を生成します。


1
実際、私はCの回答でも同じことをしています:)くそー、Haskellが仕事に最適なツールだとはどうしてわからないのでしょうか。P+1
NiklasB。14年

x>0配列をインクリメントするのではなく、ネガを含むリストを並べ替えるので、チェックを逃しますか?一方、y a bHaskellを実行するには範囲(my )を制限する必要があり、これには数文字のコストがかかります。しかし、組み込みのソート機能を備えた別の言語が存在しなければならないので、同じように作業する必要があります(Mathematicaを見てください)。
バザーグ14年

はい、残念ながらCでのソートはHaskellほど簡単ではありません。Mathematicaの問題は、コンパイルされていないため、非常に遅いことです:(
Niklas B. 14年

他の言語がより良い場合でも、私は常にHaskellで練習のためにこれらを行います。
バザーグ14年

私はそれもここでそれを使用するように私には発生しなかったことに困惑ので、私は実際には、副業としてハスケルをプログラム:Dはそれも本当の/の不純な世界では、本当に素晴らしい言語だ
ニクラスB.

10

Java (1517-75.85)= 1441.15 (1429-71.45)= 1357.55(1325-66.25)= 1258.75

これは楽しかったです。

ミラーリングと回転に関するすべてのユニークなソリューションを快適なハニカムで印刷します(したがって5%削減)

ランタイム:4歳のラップトップで〜0.122秒(122ミリ秒)。

ゴルフされたコード(編集は愚かにも自分のprintfを繰り返し、ゴルフを最大化するために1つのprintfに減らしました)(新しい編集 Set関数への呼び出しを賢い小さな関数に減らし、いくつかの他のマイクロ最適化):

import java.util.*;class A{boolean c(Set<Integer>u,int z){return!u.contains(z);}Set<Integer>b(Set<Integer>c,int...v){Set<Integer>q=new HashSet<Integer>(c);for(int x:v)q.add(x);return q;}void w(){Set<Integer>U,t,u,v,w,y,z;int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,X,Z;X=20;Z=38;for(a=1;a<X;a++)for(b=1;b<X;b++)if(b!=a)for(c=1;c<X;c++)if(c!=a&&c!=b&&a+b+c==Z){U=b(new HashSet<Integer>(),a,b,c);for(d=1;d<X;d++)if(c(U,d))for(h=1;h<X;h++)if(h!=d&&c(U,h)&&a+d+h==Z){t=b(U,a,b,c,d,h);for(m=1;m<X;m++)if(c(t,m))for(q=1;q<X;q++)if(q!=m&&c(t,q)&&h+m+q==Z){u=b(t,m,q);for(r=1;r<X;r++)if(c(u,r))for(s=1;s<X;s++)if(s!=r&&c(u,s)&&q+r+s==Z){v=b(u,r,s);for(p=1;p<X;p++)if(c(v,p))for(l=1;l<X;l++)if(l!=p&&c(v,l)&&s+p+l==Z){w=b(v,p,l);for(g=1;g<X;g++)if(c(w,g)&&l+g+c==Z)for(e=1;e<X;e++)if(e!=g&&c(w,e))for(f=1;f<X;f++)if(f!=e&&f!=g&&c(w,f)&&d+e+f+g==Z){y=b(w,g,e,f);for(i=1;i<X;i++)if(c(y,i))for(n=1;n<X;n++)if(n!=i&&c(y,n)&&d+i+n+r==Z&&b+e+i+m==Z){z=b(y,i,n);for(o=1;o<X;o++)if(c(z,o))for(k=1;k<X;k++)if(k!=o&&c(z,k)&&m+n+o+p==Z&&r+o+k+g==Z&&b+f+k+p==Z)for(j=1;j<X;j++)if(c(z,j)&&j!=o&&j!=k&&a+e+j+o+s==Z&&c+f+j+n+q==Z&&h+i+j+k+l==Z){System.out.printf("%6d%4d%4d\n\n%4d%4d%4d%4d\n\n%2d%4d%4d%4d%4d\n\n%4d%4d%4d%4d\n\n%6d%4d%4d\n\n",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s);return;}}}}}}}}}public static void main(String[]a){(new A()).w();}}

ブルートフォースは無難ですが、解の非常に小さなセットのみが存在するという事実を巧みに使用することで、反復ベースの回答が得られました。反復の各ループ内では、まだ「割り当てられていない」整数のみを考慮します JavaのHashSetを使用して、以前に使用された数値のO(1)ルックアップを取得します。最後に、正確に12のソリューションがありますが、ローテーションとミラーリングの両方を割引にすると、これはたった1つのユニークなソリューションになります。このソリューションにどのように取り組んでいるかについてのより明確な見解については、GitHubゴルフの少ないコードをチェックしてください。

楽しい!


まあ、あなたはあなたのネタバレに横たわっています、より多くの異なる解決策があるので、あなたの答えは無効です。
ST3

強い主張、それを証明するためにあなた自身の答えでそれをバックアップできますか?ネタバレに意図的な嘘があることは確かに知りません。
プログラマー

したがって、最初の解決策が見つかった場合、それを印刷して、ルールno を終了します。3はすべての答えを見つけるように告げます。OPが言ったように19ありますが、本当に19かどうかはわかりませんが、以前にも同様のタスクに遭遇したことがあるので、1つ以上あることを知っています。
ST3

あなたは私のネタバレを全部読む必要があります。12のソリューションを見つけました。次に、質問に添付されているコメント全体を読む必要があります。OPは、wrt回転が等しい回答は同等であり、スキップする必要があると述べています。別の人は、ミラーリングと同等の回答をスキップするかどうか尋ねました。OPはこのクエリに応答していませんが、これまでのところ、私と他のすべてのソリューションは、答えが「はい」であると想定しています。したがって、私のソリューションは完全に完全かつ正確であり、ここには「嘘」はありません。ただし、12個すべてのソリューションを表示する場合は、return;ステートメントを削除してください。
プログラマー

最後に、これはコードゴルフです。任意のreturn;ステートメントを追加するとコードの長さが7増えることを考慮すると、真の答えに単純に相互にローテーション/ミラーリングされた12のソリューションすべてが含まれている場合、コードを追加するのは正気ではありません。狂気を排除することはできませんが、この場合、追加return;は意図的であり、私が説明したように、完全な質問とコメントダイアログに基づいて、告発を投げる前に確認する必要があります。ありがとう!
プログラマー

8

C、366バイト(C ++ 541 450

#define R(i)for(int i=19;i;--i)
#define X(x)if(x>0&&!V[x]++)
#define K(X)X(a)X(b)X(c)X(d)X(e)X(f)X(g)X(h)X(i)X(j)X(k)X(l)X(m)X(n)X(o)X(p)X(q)X(r)X(s)
Q(x){printf("%d ",x);}
T=38,V[99];main(){R(h)R(c)R(s)R(a)R(l)R(q)R(e){int d=T-a-h,b=T-a-c,g=T-c-l,p=T-l-s,r=T-q-s,m=T-h-q,f=T-g-e-d,i=T-b-e-m,n=T-d-i-r,o=T-p-n-m,k=T-g-o-r,j=T-h-i-k-l;R(C)V[C]=0;K(X)K(+Q),exit(0);}}

でコンパイルしgcc -std=c99 -O3ます。

回転とミラーリングを法とするすべてのユニークなソリューションをa b c d ...、行ごとに1つの形式で出力します。

ランタイム:コンピューターで0.8秒。

最大プルーナビリティのために、h-> c-> s-> a-> l-> q-> eの順にセルを列挙します。実際、上記のバージョンは、それらの変数に対して20 ^ 7の割り当てをすべて試行します。その後、他のすべてのセルを計算できます。回転/ミラーリングをモジュロ化する唯一のユニークなソリューションがあります。Githubには、古くてゴルフが少なく、最大20倍高速な(プルーニングによる)C ++バージョンがあります


ここでは、主に算術的なアプローチが大好きです。ブラボー!+1
プログラマー

1

Matlab:333 320文字

これは、再帰を使用しない、非常に馬鹿げた強引なアプローチです。で部分的なソリューションを構築しz、最後に印刷します。各列はソリューションです。要素は上から下にリストされています。ランタイムは1〜2時間です。

z=[];
a='abc adh hmq qrs spl lgc defg beim mnop dinr rokg pkfb hijkl aejos cfjnq';while a[k,a]=strtok(a);n=length(k);x=nchoosek(1:19,n)';s=[];for t=x(:,sum(x)==38)s=[s,perms(t)'];end
m=0.*s;m(19,:)=0;m(k(1:n)-96,:)=s(1:n,:);y=[];for p=m for w=z m=[];l=w.*p~=0;if p(l)==w(l) y(:,end+1)=w+p.*(~l);end
end
end
z=[m,y];end
z

Matlab内から実行:

>> aristotle;
>> z(:,1)

ans =

    9
   11
   18
   14
    6
    1
   17
   15
    8
    5
    7
    3
   13
    4
    2
   19
   10
   12
   16
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.