我有以下python代码:
def sum_fibonacci():
'''Project Euler: 2
Sum of even-valued terms of Fibonacci sequence < 4 mil
'''
def i(a, b, acc):
if a >= 4000000: return acc
if a % 2 == 0:
return i(a + b, a, acc + a)
else: return i(a + b, a, acc)
return i(2, 1, 0)
我想将其翻译成Emacs Lisp。在ELISP中的高阶功能中,我被告知不要在defun
中使用defun
,因为它可以在全球范围内启用该功能,因此我写了Lambda。但是我需要递归地召集lambda。
我的代码是:
(defun sum-fibonacci ()
(let ((i
(lambda (a b acc)
(cond ((>= a 4000000) acc)
((evenp a) (funcall i (+ a b) a (+ a acc)))
(t (funcall i (+ a b) a acc))))))
(funcall i 2 1 0)))
但是,在用 let
分配的函数 i
是调用的,我有一个错误- *** Eval error *** Symbol's value as variable is void: i
我如何在elisp中的lambda中进行递归?
是的,您可以在emacs lisp中执行此操作。
(funcall (lambda (fib a b acc) (funcall fib a b acc fib)) ;;lambda1
(lambda (a b acc fib) ;;lambda2
(cond ((>= a 40000) acc)
((zerop (mod a 2)) (funcall fib (+ a b) a (+ acc a) fib))
(t (funcall fib (+ a b) a acc fib))))
2 1 0)
主要想法是使用助手兰巴达(lambda1
)调用真实的lambda(lambda2
),然后将真实的lambda( lambda2
)传递给本身。
在lambda函数中每卷曲我用 labels
重写:
(defun sum-fibonacci ()
(labels ((i (a b acc)
(cond ((>= a 4000000) acc)
((evenp a) (i (+ a b) a (+ a acc)))
(t (i (+ a b) a acc)))))
(i 2 1 0)))
只需删除lambda列表中的逗号:
(defun sum-fibonacci ()
(labels ((rec (a b acc)
(cond ((>= a 4000000) acc)
((evenp a) (rec (+ a b) a (+ a acc)))
(t (rec (+ a b) a acc)))))
(rec 2 1 0)))