common-lisp版汉诺塔
1.定义三根柱子,pillar-1 pillar-2 pillar-3, 每根柱子有自己的属性:name(柱子名称),value(柱子上的盘子),为了打印盘子的移动过程,我们给每根柱子定义了名称。
(defparameter pillar-1 nil)
(setf (getf pillar-1 'value) '(1 2 3 4))
(setf (getf pillar-1 'name) "pillar-1")
(defparameter pillar-2 nil)
(setf (getf pillar-2 'value) '())
(setf (getf pillar-2 'name) "pillar-2")
(defparameter pillar-3 nil)
(setf (getf pillar-3 'value) '())
(setf (getf pillar-3 'name) "pillar-3")
pillar-1上有四个盘子,我们最后会把这4个盘子借助pillar-2移动到pillar-3上。
2. 递归函数:
(defun Move (n source-pillar aim-pillar via-pillar)
(if (= n 1) ;当要移动的盘子数为1,则移动后不在递归
(progn
(print (format nil "----move ~a plates from ~a to ~a ~%" n (getf source-pillar 'name) (getf aim-pillar 'name)))
(pop (getf source-pillar 'value))
(push n (getf aim-pillar 'value))
(format nil "pillar-~a:~{~a ~}" 1 pillar-1)
(format nil "pillar-~a:~{~a ~}" 2 pillar-2)
(format nil "pillar-~a:~{~a ~}" 3 pillar-3)
)
(progn ;移动的盘子数大于1
(print (format nil "----move ~a plates from ~a to ~a ~%" n (getf source-pillar 'name) (getf aim-pillar 'name)))
(Move (- n 1) source-pillar via-pillar aim-pillar) ;把n-1个盘子移动到辅助柱子上
(push n (getf aim-pillar 'value)) ;把第n个盘子移动到目标柱子上
(pop (getf source-pillar 'value)) ;
(Move (- n 1) via-pillar aim-pillar source-pillar) ;把n-1个盘子从辅助柱子移动到目标柱子上
)))
根据common-lisp的思想,也可以在Move函数内写个递归实现的。
函数说明:
I.函数的参数 Move (n source-pillar aim-pillar via-pillar)
n:要移动的盘子数量,在此,同时说明要移动的是那几个盘子,从编号1到n之间的所有盘子(从小到大,数字越小,代表盘子越小)。
source-pillar:初始柱子,即当前盘子所在的柱子。
aim-pillar:目标柱子,盘子要移动到的柱子。
via-pillar:辅助柱子。
3.调用: (Move 4 pillar-1 pillar-3 pillar-2)
4.查看结果:(getf pillar-3 'value)