2

私は次の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)

それをEmacsLispに翻訳したいと思います。Elispの高階関数では、関数をグローバルに有効にするため、defun内で使用しないように指示されたため、代わりにラムダを記述しました。defunしかし、ラムダ呼び出し自体を再帰的に行う必要があります。

私のコードは次のとおりです。

(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)))

ただし、関数iが割り当てられる前に関数が呼び出されlet、エラーが発生します-*** Eval error *** Symbol's value as variable is void: i

Elispのラムダで再帰を行うにはどうすればよいですか?

4

3 に答える 3

4

はい、emacslispでこれを行うことができます。

(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)

主なアイデアは、ヘルパーlambda()を使用しlambda1て実際のラムダ()を呼び出し、実際のラムダ( )をそれ自体lambda2に渡すことです。lambda2

于 2012-11-13T13:43:20.943 に答える
4

ラムダ関数での再帰ごとに、次のように書き直しました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)))
于 2012-11-13T07:53:43.547 に答える
2

ラムダリストのコンマを削除するだけです。

(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)))
于 2012-11-13T07:34:11.570 に答える