For an assignment I have to create Towers of Hanoi in Common LISP with named discs. I need to get output that looks something like this:
[1]> (hanoi '(Small Medium Large))
Moved SMALL from Peg 1 to Peg 3
Moved MEDIUM from Peg 1 to Peg 2
Moved SMALL from Peg 3 to Peg 2
Moved LARGE from Peg 1 to Peg 3
Moved SMALL from Peg 2 to Peg 1
Moved MEDIUM from Peg 2 to Peg 3
Moved SMALL from Peg 1 to Peg 3
NIL
[2]> peg1
NIL
[3]> peg2
NIL
[4]> peg3
(Small Medium Large)
Yet when I run the program I have created I get output like this:
[1]> (hanoi '(Small Medium Large))
Move SMALL from Peg 1 to Peg 2
Move SMALL from Peg 1 to Peg 2
Move NIL from Peg 2 to Peg 2
Move SMALL from Peg 1 to Peg 2
Move NIL from Peg 2 to Peg 1
Move NIL from Peg 2 to Peg 2
Move SMALL from Peg 1 to Peg 2
NIL
[2]> peg1
(Small Medium Large)
[3]> peg2
NIL
[4]> peg3
NIL
Here is my code:
(defvar *peg1* '())
(defvar *peg2* '())
(defvar *peg3* '())
(defun peg-name (peg)
(cond ((equal peg *peg1*) "Peg 1")
((equal peg *peg2*) "Peg 2")
((equal peg *peg3*) "Peg 3")))
(defun move-disk (from to)
(format t "Move ~a from ~a to ~a~%" (first from) (peg-name from) (peg-name to))
(push (pop from) to))
(defun transfer (n source aux dest)
(if (> n 0)
(progn
(transfer (1- n) source dest aux)
(move-disk source dest)
(transfer (1- n) aux source dest))))
(defun hanoi (disk-list)
(setq *peg1* disk-list)
(transfer (length disk-list) *peg1* *peg2* *peg3*))
The problem with the code is obviously the move-disk function, since it is just throwing away the result after it is called. But I am not sure how exactly I can determine which of the global variables I should be pushing and popping from. I've fiddled with using a large list to represent the tower and having the pegs be sublists in it, but I have the same problem of determining what part of the list to modify. Any help would be appreciated. I feel like I am at a complete dead end.