「prolog勉強26日目 雑多なパズル一覧」の編集履歴(バックアップ)一覧に戻る

prolog勉強26日目 雑多なパズル一覧 - (2013/06/30 (日) 06:39:08) の編集履歴(バックアップ)


ナイトの交換というパズルを解くPrologプログラム。
盤面サイズは3*4。

move_t(0,5).
move_t(0,7).
move_t(1,6).
move_t(1,8).
move_t(2,3).
move_t(2,7).
move_t(3,8).
move_t(3,10).
move_t(4,9).
move_t(4,11).
move_t(5,6).
move_t(5,10).
move_t(6,11).
move_t(8,9).
move_perm(From,To):-move_t(From,To).
move_perm(From,To):-move_t(To,From).

print_path([]).
print_path(State):-state_chain(OldState,State),print_path(OldState),
	one_print(State,[0,1,2,n,3,4,5,n,6,7,8,n,9,10,11,n,n]).
print_rev_path([]).
print_rev_path(State):-one_print(State,[0,1,2,n,3,4,5,n,6,7,8,n,9,10,11,n,n]),
	state_chain(State,NextState),print_rev_path(NextState).

one_print([],[]):-!.
one_print(Log,[n|Rest]):-!,nl,one_print(Log,Rest).
one_print([[P,C]|Rest],[P|Rest1]):-!,write(C),one_print(Rest,Rest1).
one_print(Log,[_|Rest]):-write(s),one_print(Log,Rest).



all_next_search(N):-
	N1 is N+1,
	state_list(N,State),
	move_perm(From,To),
select([From,Color],State,Rest1),
	not(member([To,_],Rest1)),
	Temp=[[To,Color]|Rest1],
	sort(Temp,NextState),
	not(state_chain(_,NextState)),
	assert(state_chain(State,NextState)),
	assert(state_list(N1,NextState)),
	state_rev_list(_,NextState),
print_path(State),
 	print_rev_path(NextState),
	read(A),write(A).


all_old_search(N):-
	N1 is N+1,
	state_rev_list(N,State),
	move_perm(From,To),
	select([From,Color],State,Rest1),
	not(member([To,_],Rest1)),
	Temp=[[To,Color]|Rest1],
	sort(Temp,OldState),
	not(state_chain(OldState,_)),
	assert(state_chain(OldState,State)),
	assert(state_rev_list(N1,OldState)),
	state_list(_,OldState),
	print_path(OldState),
	print_rev_path(State),
	read(A),write(A).


next_search(N):-
	N <12,
	not(all_next_search(N)),
	not(all_old_search(N)),
	findall(State,state_list(N,State),List),length(List,Len),write([Len,l]),
	N1 is N+1,
	write(N1),nl,
	next_search(N1).

main:-     State=[[0,b],[1,b],[2,b],[9,w],[10,w],[11,w]],
StateRev=[[0,w],[1,w],[2,w],[9,b],[10,b],[11,b]],
 	assert(state_rev_list(0,StateRev)),
	assert(state_list(0,State)),
	assert(state_chain([],State)),
	retractall(state_list(_,_)),
	retractall(state_chain(_,_)),
	retractall(state_rev_list(_,_)),
	assert(state_list(0,State)),
	assert(state_chain([],State)),
	assert(state_chain(StateRev,[])),
	assert(state_rev_list(0,StateRev)),
	next_search(0).




http://blog.goo.ne.jp/handbill-puzzle/e/f5d4013bfeefba4607977c1faebbb05a
こちらのサイトにあったじゃんけんパズルその5を解かせた。
多分手作業で問いたら1分で解ける気もする。
コードももっと短くならないかなこれ?

con(1,[0,2]).
con(0,[1,3]).
con(3,[0,1,2,3,4,5]).
con(1,[2,6]).
con(1,[3,5,7]).
con(1,[4,6,7]). 

te(1,pa):-!.
te(7,gu):-!.
te(_,gu).
te(_,tyoki).
te(_,pa). 

v_count([Gu,Tyoki,Pa],0):-0<Gu,0<Tyoki,0<Pa,!.
v_count([_,0,0],0):-!.
v_count([0,_,0],0):-!.
v_count([0,0,_],0):-!.
v_count([Gu,_,0],Gu):-!.
v_count([_,0,Pa],Pa):-!.
v_count([0,Tyoki,_],Tyoki).

add(gu,Gu,Tyoki,Pa,ReGu,Tyoki,Pa):-
	ReGu is Gu+1.
add(tyoki,Gu,Tyoki,Pa,Gu,ReTyoki,Pa):-
	ReTyoki is Tyoki+1.
add(pa,Gu,Tyoki,Pa,Gu,Tyoki,RePa):-
	RePa is Pa+1.


te_count(_,[],[0,0,0]):-!.
te_count(List,[P|Rest],[ReGu,ReTyoki,RePa]):-
	member([P,Te],List),
	te_count(List,Rest,[Gu,Tyoki,Pa]),
	add(Te,Gu,Tyoki,Pa,ReGu,ReTyoki,RePa).

ans_check(Ans,[]):-write(Ans).
ans_check(List,[[V,Perm]|Rest]):-
	te_count(List,Perm,TeCount),
	v_count(TeCount,NowV),
	V=:=NowV,
	ans_check(List,Rest).

search(N,List):-
	N=:=8,!,
	reverse(List,List1),
	findall([V,Perm],con(V,Perm),AllSet),
	ans_check(List1,AllSet).

search(N,List):-
	te(N,Te),
	N1 is N+1,
	search(N1,[[N,Te]|List]).