Lisp UVa 10120礼物?!用公共口齿不清?

Lisp UVa 10120礼物?!用公共口齿不清?,lisp,common-lisp,Lisp,Common Lisp,我正在学习CommonLisp,我在uVA数据库中遇到了一个问题(http://acm.uva.es/p/v101/10120.html)还有一个广度搜索功能(包括起点、目标点和合法移动生成器),我已经掌握了如何获得答案的理论,但Lisp并不同意我的观点。我可以就如何从这一点开始提出一些建议吗?下面是一个链接,指向给定的问题和我尝试的两个lisp源代码解决方案。任何帮助都将不胜感激!谢谢 一, 如上所述,总体思路是简单地对给定的合法移动生成器应用广度搜索函数,希望通过分析它的输出,我们可以确定是

我正在学习CommonLisp,我在uVA数据库中遇到了一个问题(http://acm.uva.es/p/v101/10120.html)还有一个广度搜索功能(包括起点、目标点和合法移动生成器),我已经掌握了如何获得答案的理论,但Lisp并不同意我的观点。我可以就如何从这一点开始提出一些建议吗?下面是一个链接,指向给定的问题和我尝试的两个lisp源代码解决方案。任何帮助都将不胜感激!谢谢

一,


如上所述,总体思路是简单地对给定的合法移动生成器应用广度搜索函数,希望通过分析它的输出,我们可以确定是否能够达到目标状态。如果上面的代码太混乱,我很乐意回答任何问题,再次感谢

在其他潜在问题中:

你使用循环错误。有关循环的信息,请参阅。我把它改了一点,但我不知道你在尝试什么

SETF比SETQ更通用,因此建议使用SETF

INCF将一个位置增加1

你的压痕不好;如果你修正了这个问题,你会注意到你从秒末掉到了循环中。我建议在这里使用Lisp时使用自动缩进编辑器。(Emacs为备用)

(德芬礼品(N G)
(setq CR 9)
(setq i 3)
(cond(=ng)“N和G相等”)
(((n49)“岩石的数量大于49-它将起作用”)
((CR N)
(返回“别嘲笑我!”)

在其他潜在问题中:

你使用循环错误。有关循环的信息,请参阅。我把它改了一点,但我不知道你在尝试什么

SETF比SETQ更通用,因此建议使用SETF

INCF将一个位置增加1

你的压痕不好;如果你修正了这个问题,你会注意到你从秒末掉到了循环中。我建议在这里使用Lisp时使用自动缩进编辑器。(Emacs为备用)

(德芬礼品(N G)
(setq CR 9)
(setq i 3)
(cond(=ng)“N和G相等”)
(((n49)“岩石的数量大于49-它将起作用”)
((CR N)
(返回“别嘲笑我!”)

有些事情是显而易见的:

  • 您正好有两个合法的返回值,“让我试试!”和“别取笑我!”。您错误地拼写了第一个字符串,重新表述了第二个字符串,并添加了许多与问题无关的字符串(它们是作为注释使用的吗?)
  • 描述调用变量
    N
    M
    ,但尝试使用参数
    N
    G
    。为什么要迷惑自己?或者叫他们
    N
    M
    ,或者(更好)用有意义的名字,比如
    rock number
    gift place
现在,让我们看看您的程序结构

(defun gift (N G)
  (setq CR 9)
  (setq i 3))
这些
setq
指令此时具有未定义的行为,因为
CR
I
尚未定义。许多Lisp实现都会隐式地创建这些名称的全局特殊变量,但依赖它是不好的风格。我觉得你想在这里使用
let
,就像这样:

(defun gift (rock-number gift-place)
  (let ((current-rock 0)
        (jump-number 0))
    ;; ...
    ))
请注意,你真的应该从头开始,因为当礼物放在摇滚乐1或4上时,你会错过解决方案

接下来是
cond
form:它是死代码,因为它没有副作用,您会立即丢弃它的返回值。因此,它充其量只是一个注释,您应该为此使用注释

最后,我们有一个有趣的循环:

(loop
  (setq I (+ I 1))
  (setq I (-(* I 2) 1))
  (setq CR 9) 
  (breadth-search CR G #'lmg-moves)
  (when (= CR G) (return "Let me Try!"))
  (when (> CR N) (return "Don't laugh at me!"))))
我不知道
width search
做什么,但似乎您确实依赖于全局特殊变量的操作。我说不出这里会发生什么。然而,我可以看到几个问题:

  • 当你从给定的岩石跳到一定距离时,你最多可以有两个位置。每次跳转后只检查一个变量是不对的
  • 你似乎混淆了跳跃次数和跳跃距离<代码>I按顺序1、3、7、15…,但跳转编号顺序为1、2、3、4…,而跳转距离顺序为1、3、5、7…。即使是在总是向右跳跃时访问的岩石也是不同的序列(1、4、9、16…)
  • 每次通过循环将
    CR
    重置为9。我不明白这怎么可能是对的
在风格上,您应该尽可能地保持变量的局部性,例如使用
let
do
,或扩展的
循环
关键字
:for
:with
,然后将它们传递到需要它们作为参数的函数中。这使得对正在发生的事情进行推理变得更加容易

我认为你的解决方案算法的心智模型有点混乱。我会以这样一种方式构造它,你在跳跃中循环,并保留一组岩石,你可以在精确的跳跃次数后继续。特殊的
(defun gift (N G)
  (setq CR 9)
  (setq i 3))
(defun gift (rock-number gift-place)
  (let ((current-rock 0)
        (jump-number 0))
    ;; ...
    ))
(loop
  (setq I (+ I 1))
  (setq I (-(* I 2) 1))
  (setq CR 9) 
  (breadth-search CR G #'lmg-moves)
  (when (= CR G) (return "Let me Try!"))
  (when (> CR N) (return "Don't laugh at me!"))))