「prolog勉強22日目 カラーダイスパズル」の編集履歴(バックアップ)一覧に戻る

prolog勉強22日目 カラーダイスパズル - (2013/06/23 (日) 07:56:46) のソース

Prolog勉強22~23日目。
ページ作者 堀江伸一

prologのassertは関数の参照透過性を破壊する可能性があるから原理主義的にはこのましいものではないのか?
Prologの関数を書いててふと思った疑問です。
調べてみたらどうもこの話、Prologが世に出た時から議論されてるそうです。
詳細は今勉強中。


http://www.geocities.jp/m_hiroi/puzzle/colordice.html
さて創価学会員からは小学校の算数までしかできないと噂されている堀江伸一こと私の今日の勉強です。
今日の勉強はこちらのサイトにあるパズルをprologで解いてみました。 
カラーダイスパズルです。

単純に回転した場合の写像をとって全パタンを試しただけ、この手の回転は群論の初歩的な感じかも。
深さ優先探索がサクッと書けるのはプロローグの強みだと思う。
こんなパズルでも、データ構造や写像をどう定義するかでそれなりに遊びどころはある。
プロローグはデータをどう定義するかでコードの総量が極端に変わるとわかりそこは良い勉強になった。
適当に書いても重複解を排除できるかと思ったら意外と排除できなかったので重複解を排除するコードを後からつけ足してみた。
flat_roundsは事実とした方がよかったか。 

  
 flat_round([U,D,F,L,B,R],[U,D,R,F,L,B]).
 down_round([U,D,F,L,B,R],[B,F,U,L,D,R]).
 flat_rounds(A,A).
 flat_rounds(A,Re):-flat_round(A,Re).
 flat_rounds(A,Re1):-flat_round(A,Re),flat_round(Re,Re1).
 flat_rounds(A,Re2):-flat_round(A,Re),flat_round(Re,Re1),flat_round(Re1,Re2).
 
 all_down(A,A).
 all_down(A,Re2):-flat_rounds(A,Re1),down_round(Re1,Re2).
 all_down(A,Re2):-down_round(A,Re1),down_round(Re1,Re2).
 
 one_print([U,D,F,L,B,R]):-
 	format('_~a~n',U),
 	format('~a~a~a~a~n',[R,F,L,B]),
 	format('_~a~n',D).
 
 print_xai([]):-!.
 print_xai([Xai|Rest]):-one_print(Xai),print_xai(Rest).
 
 flat_check([],_).
 flat_check([_|Rest],Xais):-
 	not(answers(Xais)),
         all_flat_round_xai(Xais,Xais1),
 	flat_check(Rest,Xais1).
 
 answer_check(Xais):-
 	flat_check([0,1,2,3],Xais),
 	all_reverse_xai(Xais,Xais2),
         flat_check([0,1,2,3],Xais2),
 	assert(answers(Xais)),
 	print_xai(Xais).
 
 all_flat_round_xai([],[]).
 all_flat_round_xai([Xai|Rest],[Xai1|Result]):-
 	all_flat_round_xai(Rest,Result),flat_round(Xai,Xai1).
 
 all_reverse_xai([],[]).
 all_reverse_xai([Xai|Rest],[Xai2|Result]):-
        down_round(Xai,Xai1),down_round(Xai1,Xai2),
        all_reverse_xai(Rest,Result).
 
 search([],_,_,_,_,Log):-
 	!,answer_check(Log).
 search([T|Rest],Fs,Ls,Bs,Rs,Log):-
 	xais(T,Xai),
 	all_down(Xai,Xai1),
 	flat_rounds(Xai1,Xai2),
 	[_,_,F,L,B,R]=Xai2,
 	not(member(F,Fs)),
 	not(member(L,Ls)),
 	not(member(R,Rs)),
 	not(member(B,Bs)),
 	search(Rest,[F|Fs],[L|Ls],[B|Bs],[R|Rs],[Xai2|Log]).
 
 first([T|Rest]):-
 	xais(T,Xai),
 	all_down(Xai,Xai1),
 	[_,_,F,L,B,R]=Xai1,
 	search(Rest,[F|[]],[L|[]],[B|[]],[R|[]],[Xai1|[]]).
 
 main:-
 	assert(xais(0,[])),
 	assert(answers([])),
 	retractall(xais(_,_)),
 	retractall(answers(_)),
 	assert(xais(0,[b,b,g,g,y,r])),
 	assert(xais(1,[b,r,b,g,y,r])),
 	assert(xais(2,[r,b,g,y,y,r])),
 	assert(xais(3,[g,r,g,y,g,b])),
 	first([0,1,2,3]).