Skip to content

Instantly share code, notes, and snippets.

@irvifa
Created February 1, 2016 06:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save irvifa/8e6aa03e70541951eb14 to your computer and use it in GitHub Desktop.
Save irvifa/8e6aa03e70541951eb14 to your computer and use it in GitHub Desktop.
solver with prolog
connected(a,b).
connected(b,c).
connected(c,a).
connected(a,e).
connected(e,c).
connected(c,d).
connected(d,e).
connected(e,b).
eulerianpath(Edges, Res) :-
setof(From-To, call(Edges, From, To), Acc),
travel(Acc, Res).
travel([], [_]).
travel(L, [Now,Next|Rest]) :-
select(From-To,L,Tmp),
( From = Now, To = Next ; To = Now,From = Next ),
travel(Tmp, [Next|Rest]).
gen(S,L):-S=[H|T],gen(H,T,[],L).
gen(_,[],L,L):-!.
gen(H,[X|Y],T,L):-gen(X,Y,[[H,X]|T],L).
rev(S,L):-rev(S,[],L).
rev([],Z,Z).
rev([H|T],Acc,Z) :- rev(T,[H|Acc],Z).
%for the purpose of debug only
%test(L):-eulerianpath(connected,L).
solver(S):-eulerianpath(connected,L),gen(L,Z),rev(Z,S).
% Find all possible path
sum_of_solution(S):-findall(T,solver(T),Z),length(Z,S).
dist(1,2).
dist(2,1).
dist(2,-1).
dist(1,-2).
dist(-1,-2).
dist(-2,-1).
dist(-2,1).
dist(-1,2).
move(Boundary,X1/Y1,X2/Y2) :-
dist(X,Y),
X2 is X1+X, X2 > 0, X2 =< Boundary,
Y2 is Y1+Y, Y2 > 0, Y2 =< Boundary.
knights(_,0,Knights,Knights).
knights(N,M,Visited,Knights) :-
Visited = [X/Y|_],
move(N,X/Y,U/V),
\+ member(U/V,Visited),
M1 is M-1,
knights(N,M1,[U/V|Visited],Knights).
knights(N,Knights) :- M is N*N-1, knights(N,M,[1/1],Knights).
findall_solution(N,S) :- findall(Knights,knights(N,Knights),L), length(L,S).
/**
* Generate solution for N-Queens problem
*/
solution(_,[]):-!.
solution(N,[X/Y|Others]) :-
gen(N,L),solution(N,Others),member(Y, L),
noattack(X/Y, Others).
noattack(_,[]).
noattack(X/Y,[X1/Y1|Others]) :-
Y =\= Y1,
Y1 - Y =\= X1 - X,
Y1 - Y =\= X - X1,
noattack(X/Y,Others).
member(Item,[Item|_]).
member(Item,[_|Rest]) :-
member(Item,Rest).
% generate a list
gen(N, L) :- gen(N, [], L).
gen(0, L, L) :- !.
gen(N, R, L) :- N > 0, N1 is N-1, gen(N1, [N|R], L).
var(N,L):-length(L,N).
unif([],[],_).
unif([HL|L],[HR|R],[HL/HR|S]):-unif(L,R,S).
% map of solver
row(_,[]):-!.
row(I,[_/Y|Tail]):- (I = Y), write(*),row(I,Tail),!.
row(I,[_|Tail]):- write(-), row(I,Tail).
col(0,_):- !.
col(I,X):- row(I,X),put(10),I1 is I - 1, col(I1,X).
draw(S):- length(S,L),col(L,S).
% solver
queens(N,S):-gen(N,L),var(N,R),unif(L,R,S),solution(N,S),draw(S).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment