Common Lisp函数返回错误的值

时间:2013-01-06 22:20:21

标签: common-lisp

我正在尝试项目的euler问题来学习常见的lisp,而且我很早就陷入了困境。在问题1上,问题是从1到1000的整数之和。我认为下面的代码应该这样做,但它总是返回end(如果它是mod 3或mod 5)或0的值。

(defun mod3or5 (n)                                                                 
  (cond                                                                            
    ((equal (mod n 5) 0) n)                                                        
    ((equal (mod n 3) 0) n)                                                        
    (0))))                                                                         

(defun mod-sum (start end)                                                         
  (cond                                                                            
    ((equal start end) (mod3or5 start))                                            
    (+ (mod3or5 start) (mod-sum (+ start 1) end)))) 

例如

(mod-sum 1 9)
=> 9
(mod-sum 1 8)
=> 0

我希望答案分别为23和14。

2 个答案:

答案 0 :(得分:5)

提供给cond的每个表单都具有(condition exp1 ... expn)形式。如果condition为真,它将评估所有表达式并返回expn的值。如果condition为false,则会继续显示下一个表单。

您的上一个表单是:(+ (mod3or5 start) (mod-sum (+ start 1) end))。所以这里+是条件(因为+是一个函数而不是nil),所以它总是为真,(mod3or5 start)是第一个表达式(将被评估,但是没有返回)并且(mod-sum (+ start 1) end)是最后一个表达式(将被评估然后返回)。

cond中的“其他分支”是通过选择t作为条件来实现的。所以你的最后一个表格应该是这样的:

(t (+ (mod3or5 start) (mod-sum (+ start 1) end)))

答案 1 :(得分:0)

之前我发布了这个,但它是在Scheme中,所以我决定稍微重写它,使用loop进行更改:

(defun euler-1 ()
  (loop with x = (list 3 2 1 3 1 2 3)
     for i in (nconc x x)
     while (< (+ steps i) 1000)
     summing i into steps
     summing steps into result
     finally (return result)))

这就是你如何做到这一点,避免模数(因为它很昂贵)。你也可以平均步数2(跳过你不必添加的数字)。