以下のパズル(ゼブラパズルというらしい)を制約論理プログラミングで解いてみた。
問題:
1.家が3軒あります。その3軒の家はそれぞれ赤・青・緑で塗られています。そしてその住人は、それぞれ異なる国籍で、それぞれ異なるペットを買っています。
2.イギリス人は赤い家に住んでいます。
3.スペイン人は犬を飼っています。
4.日本人は、猫を飼っている人の右側に住んでいます。
5.猫を飼っている人は青色の家の左に住んでいます。
誰がシマウマを飼っているでしょうか?
プログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
:-use_module(library(clpfd)). zebra_prob:- % left ------> right House=[Color1,Color2,Color3], Pet=[Pet1,Pet2,Pet3], Race=[Race1,Race2,Race3], % Race 1:Japanese 2:English 3:Spanish % Color 1:Red 2:Blue 3:Green % Pet 1:Cat 2:Dog 3:Zebra all_different(House), %それぞれ異なる色の家 all_different(Pet), %それぞれ異なるペット all_different(Race), %それぞれ異なる国籍 House ins 1..3, Pet ins 1..3, Race ins 1..3, %イギリス人(2)は赤い家(1) Color1 #= 1 #<==> Race1 #= 2, Color2 #= 1 #<==> Race2 #= 2, Color3 #= 1 #<==> Race3 #= 2, %スペイン人(3)は犬(2)を飼っている Race1 #= 3 #<==> Pet1 #= 2, Race2 #= 3 #<==> Pet2 #= 2, Race3 #= 3 #<==> Pet3 #= 2, %日本人(1)は、猫(1)を飼っている人の右側 Pet1 #= 1 #<==> Race2 #= 1, Pet2 #= 1 #<==> Race3 #= 1, Race1 #\= 1, %日本人は一番左ではない %猫(1)を飼っている人は青色の家(2)の左に住んでいます。 Pet1 #= 1 #<==> Color2 #= 2, Pet2 #= 1 #<==> Color3 #= 2, Pet3 #\= 1, %猫は一番右ではない label(House), label(Pet), label(Race), write('house:'),write(House),nl, write('pet:'),write(Pet),nl, write('race:'),write(Race). |
実行結果
1 2 3 4 5 6 7 8 9 |
1 ?- zebra_prob. house:[1,2,3] pet:[1,3,2] race:[2,1,3] true ; house:[3,1,2] pet:[2,1,3] race:[3,2,1] true. |
解説
Race 1:Japanese 2:English 3:Spanish
Color 1:Red 2:Blue 3:Green
Pet 1:Cat 2:Dog 3:Zebra
PetがZebra(3)と同じ要素番号のRaceは必ず1(日本人)
よってシマウマは日本人が飼っている。
家、ペット、国籍 の並びの組み合わせは上記2パターンある。
※ 「~の右に」という文章を「1軒右」と解釈しています。
(2軒右も含むというコードに変更するのも簡単です)