我正在尝试项目的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。
答案 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(跳过你不必添加的数字)。