2014年3月22日土曜日

プロジェクトオイラー Problem 68 「Magic 5-gon ring」 †

Problem 68 「Magic 5-gon ring」 

下に示す図のようなものを"magic" 3-gon ringという. これは1~6の数字を当てはめて, 各列の数字の和が9となっている. これを例として説明する.
p_068_1.gif
外側のノードのうち一番小さいものの付いた列(例では4,3,2)から時計回りに回ってそれぞれ列の数字を3つ連ねて説明する. 例えば例のものは4,3,2; 6,2,1; 5,1,3という組で説明することができる.
1~6の数字を当てはめて, 各列の数字の和が等しくなるものは次の8通りある.
合計
94,2,3; 5,3,1; 6,1,2
94,3,2; 6,2,1; 5,1,3
102,3,5; 4,5,1; 6,1,3
102,5,3; 6,3,1; 4,1,5
111,4,6; 3,6,2; 5,2,4
111,6,4; 5,4,2; 3,2,6
121,5,6; 2,6,4; 3,4,5
121,6,5; 3,5,4; 2,4,6
この組の各数字を連結して, 9桁の数字で表すことができる. 例えば, 上の図のものは4,3,2; 6,2,1; 5,1,3であるので432621513である.
さて, 下の図に1~10の数字を当てはめ, 各列の数字の和が等しくなる"magic" 5-gon ringを作って, それを表す16桁または17桁の数字のうち, 16桁のものの最大の数字を答えよ.
(注, 3つの場合の例を見ても分かる通り, 列の始まりの数字を比べた時一番小さい数字で始まる列から時計回りに繋げるという条件のもとで文字列を生成する必要があります. この条件下で最大となる数字を答えてください. )
p_068_2.gif




http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2068


解法
条件を満たすか調べながら全探索するだけでも解けます。
Prolog言語

select_num(N,Nums,Nums):-integer(N),!.
select_num(N,Nums,Nums1):-!,select(N,Nums,Nums1).

ok(-1,Xa,Xa):-!.
ok(X,Xa,X):-X<Xa,!.

sum_ok(-1,Xa,Xb,Xc,Sum):-!,Sum is Xa+Xb+Xc.
sum_ok(Sum,Xa,Xb,Xc,Sum):-!,Sum=:=Xa+Xb+Xc.

calc([],_,_,[]):-
      !.
calc([[Xa,Xb,Xc]|Board],Sum,FirstNum,Nums):-
      select_num(Xa,Nums,Nums1),
      ok(FirstNum,Xa,FirstNum1),
      select_num(Xb,Nums1,Nums2),
      select_num(Xc,Nums2,Nums3),
      Xb<10,
      Xc<10,
      sum_ok(Sum,Xa,Xb,Xc,Sum1),
      calc(Board,Sum1,FirstNum1,Nums3).

main68:-
      Board=[[_,X2,X3],[_,X3,X5],[_,X5,X7],[_,X7,X9],[_,X9,X2]],
      calc(Board,-1,-1,[1,2,3,4,5,6,7,8,9,10]),
      write(Board).

0 件のコメント:

コメントを投稿