0

我认为这将是一个模糊的问题,因为我一开始并不确切知道我在做什么,但它就是这样。

我必须使用列表在普通 lisp 中解决河内塔问题。基本上,一个函数获取一个字符串(名称)列表,然后使用 peg B 将它们从 peg A 移动到 peg C 进行存储,使它们保持与列表中相同的顺序。

我以前从未使用过 lisp,而且我发现语法很难理解。这是我到目前为止的代码 goo 功能是河内的工作

(defparameter A '())
(defparameter B '())
(defparameter C '())


(defun findPeg (p1 p2) (cond ((= 0 (- 3 p1 p2))A)  
    ((= 1 (- 3 p1 p2))B) ((= 2 (- 3 p1 p2))C)))

(defun getnum (x) (cond ((equalp x A) 0)((equalp x B)1)((equalp x C) 2)))

(defun hanoi (x) (defparameter A x) (setlength A)(goo len A C B))

(defun setlength(x) (defparameter len (list-length x)))


(defun goo (leng from to via) 

    (cond ((= leng 1)(push (pop A) C)) ;base case


((goo (1- leng) from via to)(push (pop A)  B) ;say/do something i think


((goo (1- leng) via to from)(push (pop B) C) ;say/do something i think


))))

我的问题是递归调用。我对我到底应该做什么感到非常困惑。我知道我显然必须将第一个列表中的第一个字符串移动到另一个挂钩,但我不知道哪个挂钩甚至如何操作列表。我觉得我应该使用传递给 goo 函数的变量,但我不知道如何编辑它们,因为当我在函数中更改它们时,外部变量不会改变。

现在我遇到了错误

* - SYSTEM::%EXPAND-FORM: (GOO (1- LENG) FROM VIA TO) 应该是一个 lambda 表达式

这是一个递归调用,所以我不知道它为什么这么说。

基本上我只是想要一些关于在哪里继续或从哪里重新开始的提示或技巧,因为我什至不知道我的方法是否是一个好的方法。任何事情都非常感谢。谢谢

4

1 回答 1

1

首先,在 DEFUN 中使用 defparameter 几乎从来都不是正确的做法。

如果您想拥有一个词法范围的变量,请使用 LET (或简单地命名您的形式参数,如您所愿)。

其次,您((fun arg ..) (fun arg ...))的 GOO 函数中的表单上有一些内容。你想失去最外面的括号。

于 2011-10-12T14:50:32.563 回答