PERL   55
hanoi
Guest on 16th August 2022 01:04:32 AM

1. #!/usr/bin/perl6
2. % hanoi.pl
3. % Towers of Hanoi puzzle solver in Prolog.
4.
5. % Goal is to move, say, 4 disks from left peg
6. % to right peg, using the middle as a buffer.
7. % This version displays the state of the pegs after each move.
8.
9.
10. go :-
11.   P1 = [1,2,3,4],
12.   show(P1,[],[]),
13.   solve(4, left, middle, right, P1,[],[],NP1,NP2,NP3).
14.
15. % The main predicate is solve.
16. % N is the number of disks to move.
17. % They are to be moved from peg A to peg C, using B as a buffer.
18. % P1,P2,P3 give the state of the pegs before moving the disks.
19. % NNP1, NNP2, NNP3 give the new state after the disks have been moved.
20.
21. solve(N,A,B,C,P1,P2,P3,P1,P2,P3) :- N == 0.
22. solve(N,A,B,C,P1,P2,P3,NNP1,NNP2,NNP3) :-
23.   M is N - 1,
24.   solve(M, A, C, B, P1, P2, P3,NP1,NP2,NP3),
25. %  move(A, C),
26.   update(A,C, NP1,NP2,NP3,NewP1,NewP2,NewP3),
27.   solve(M, B, A, C, NewP1, NewP2, NewP3, NNP1,NNP2,NNP3).
28.
29. %move(A, B) :- write('Move disk from '),write(A),write(' to '),write(B),nl.
30.
31. update(A,B,P1,P2,P3,NewNewP1,NewNewP2,NewNewP3) :-
32.   pop(A,X,P1,P2,P3,NewP1,NewP2,NewP3),
33.   push(B,X,NewP1,NewP2,NewP3,NewNewP1,NewNewP2,NewNewP3),
34.   show(NewNewP1, NewNewP2, NewNewP3).
35.
36. % Note, the following pop and push operations work on any one
37. % of the three pegs. The Name argument tells what peg to manipulate.
38.
39. pop(Name,H,P1,P2,P3,NP1,NP2,NP3) :-
40.   Name == left,   P1 = [H|T], NP1 = T, NP2 = P2, NP3 = P3.
41. pop(Name,H,P1,P2,P3,NP1,NP2,NP3) :-
42.   Name == middle, P2 = [H|T], NP1 = P1, NP2 = T, NP3 = P3.
43. pop(Name,H,P1,P2,P3,NP1,NP2,NP3) :-
44.   Name == right,  P3 = [H|T], NP1 = P1, NP2 = P2, NP3 = T.
45.
46. push(Name,Elt,P1,P2,P3,NP1,NP2,NP3) :-
47.   Name == left, NP1 = [Elt|P1], NP2 = P2, NP3 = P3.
48. push(Name,Elt,P1,P2,P3,NP1,NP2,NP3) :-
49.   Name == middle, NP1 = P1, NP2 = [Elt|P2], NP3 = P3.
50. push(Name,Elt,P1,P2,P3,NP1,NP2,NP3) :-
51.   Name == right, NP1 = P1, NP2 = P2, NP3 = [Elt|P3].
52.
53. show(P1,P2,P3) :-
54.   write('left:  '),write(P1),nl,
55.   write('middle:'),write(P2),nl,
56.   write('right: '),write(P3),nl, nl.

Raw Paste

or to edit or fork this paste. It's free.