RSS

 

RSS


 パズルの問題で1枚の上に書いた「数字」の個数に言及するタイプのものがある。

問題:□の中に数字を1個ずつ、入れて成り立つようにしてください。

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
 この紙の上には
  1が□個
  2が□個
  3が□個
  4が□個
  5が□個 あります。
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
というようなもの。この問題自体は答えが唯一解。(*1)

この手の問題を作ろうとした。プログラムの世話になるわけだが、今回はprologを使ってみることに。(*2)

 「あてはめてはあってるかどうか調べる」的な問題はprologがあってるような気がしたので。

上記の問題を変形して1行減らした、
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
 この紙の上には
  1が□個
  2が□個
  3が□個
  4が□個 があります。
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
を解いてみることにした。これでも唯一解だったか?

prologのソースを書いていく。たぶん約20年ぶり。(*3)

「文の最後はピリオドだっけ?」「countって作ってみたがこれでいいのか」「カット(!)マークの使った方がいいんだっけか」「表示ってどうやるんだっけprintf? print? write? writeln?」「ワーニング出てるじゃん、直しておこうねぇ、やっぱり」「試してみよう、げっ動かない」・・・。

と格闘して、書き上げたのがこのソース。ちゃんと動いているようなので、まずまずOKということで。(*4)

test1:-acheck(3,1,3,1).
test2:-kouho(A),kouho(B),kouho(C),kouho(D),acheck(A,B,C,D),print(A),print(B),print(C),print(D),print('\n'),fail.

mklist(A,B,C,D,[1,A,2,B,3,C,4,D]).

acheck(A,B,C,D):-
 mklist(A,B,C,D,LIST),
 count(1,LIST,A),
 count(2,LIST,B),
 count(3,LIST,C),
 count(4,LIST,D).

kouho(0).
kouho(1).
kouho(2).
kouho(3).
kouho(4).
kouho(5).
kouho(6).
kouho(7).
kouho(8).
kouho(9).

count(_,[],0).
count(X,[X|L],C):-!,count(X,L,C2),C is C2+1.
count(X,[H|L],C):-not(X = H),count(X,L,C).

いざ、実行してみると、

1 ?- test2.
2321
3131

どうやら答えは2つあるようだ。「3131」の方は手で解いて知ってたけど、「2321」でも成立してることが判明。(*5)

 次回はソースを使いまわせるように改良して、もう少しゴツイ問題を解いてみたい意向。

(*1)~(*5) プ:何が何個をprologで 補足 参照のこと。


  • コメント (0)
  • トラックバック (0)
トラックバックURL :
http://www.iwai-masaka.jp/tb.cgi/938