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)

   

 
                 

posted @ 2012-12-21 13:50  误会僧  阅读(292)  评论(0编辑  收藏  举报