lisp 正负之间的区别

lisp difference between plus and minus

好吧,我正在用 Lisp 编写一个程序来解决拼图难题 (http://www.tilepuzzles.com/default.asp?p=12),但我的两个函数有问题。我对 "swap" 空磁贴有单独的功能,上面、下面、左侧或右侧都有一个,但只有上方和左侧有效。 switch_above 和 switch_below 之间的唯一区别是在一个中使用 + 而在另一个中使用 - (见代码),据我所知是什么导致了问题。

;;Switches the Empty tile with whatever is above it
(defun switch_above (state)
  (let ((x (nth (- (find_empty state) 3) state)))    ;;Find the number that   is above the Empty tile, set as X
    (setf (nth (find_empty state) state) x)          ;;Replace the Empty tile with X
    (setf (nth (position x state) state) 'E)) state) ;;Put Empty tile where X was

;;Switches the Empty tile with whatever is below it
(defun switch_below (state)
  (let ((x (nth (+ (find_empty state) 3) state)))    ;;Find the number that is below the Empty tile, set as X
    (setf (nth (find_empty state) state) x)          ;;Replace the Empty tile with X
    (setf (nth (position x state) state) 'E)) state) ;;Put Empty tile where X was

"state"列表是这样设置的: (1 2 3 4 E 5 6 7 8) 其中 E 是空方块

find_empty returns 空块的位置,所以它会 return 4 在上面的状态。

如上所写,switch_above 有效,但 switch_below 无效。

想一想当您在 switch_below 中执行第一个 SETF 时会发生什么。

ROTATEF 旋转位置

尝试改用 Common Lisp 宏 ROTATEF。看这个例子:

CL-USER 76 > (defun find-empty (state)
               (position 'e state))
FIND-EMPTY

CL-USER 77 > (defun switch-below (state &aux (empty-pos (find-empty state)))
               (rotatef (nth empty-pos       state)
                        (nth (+ empty-pos 3) state))
               state)
SWITCH-BELOW

CL-USER 78 > (switch-below '(1 2 3 4 E 5 6 7 8))
(1 2 3 4 7 5 6 E 8)

顺便说一句:如果有人想知道为什么我在上面的交互中使用了报价单。在 Common Lisp 中,修改文字列表的后果是未定义的。好吧,我们在一个 Lisp 监听器中(一个 Read Eval Print Loop)。 read 部分通常为每个交互分配一个全新的列表,并且在实现中通常这些列表不受任何保护。会出什么问题? a) 可以保护列表不被修改。 b) 它可以与其他列表共享结构(这可能很难被用户检测到)。

在程序中最好这样写

(switch-below (copy-list '(1 2 3 4 E 5 6 7 8)))

避免上述问题。