PERL   18

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


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