scheme - 可以简化此功能(制作更多 "fast")吗?

标签 scheme lisp computation-theory

我想知道这是否是该函数最快的版本。

(defun foo (x y)
  (cond 
   ;if x = 0, return y+1
   ((zp x) (+ 1 y)) 
   ;if y = 0, return foo on decrement x and 1
   ((zp y) (foo (- x 1) 1)) 
   ;else run foo on decrement x and y = (foo x (- y 1))
   (t (foo (- x 1) (foo x (- y 1)))))) 

当我运行它时,我通常会遇到堆栈溢出错误,所以我想找出一种方法来计算类似 (foo 3 1000000) 的东西而不使用计算机。

通过分析函数,我认为它是将 foo 嵌入到导致 (foo 3 1000000) 溢出的递归情况中。但是既然你在递减 y,那么步数是否正好等于 y?

编辑:删除评论中的谎言

最佳答案

12 年前我写了这篇文章:

(defun ackermann (m n)
  (declare (fixnum m n) (optimize (speed 3) (safety 0)))
  (let ((memo (make-hash-table :test #'equal))
        (ncal 0) (nhit 0))
    (labels ((ack (aa bb)
               (incf ncal)
               (cond ((zerop aa) (1+ bb))
                     ((= 1 aa) (+ 2 bb))
                     ((= 2 aa) (+ 3 (* 2 bb)))
                     ((= 3 aa) (- (ash 1 (+ 3 bb)) 3))
                     ((let* ((key (cons aa bb))
                             (val (gethash key memo)))
                        (cond (val (incf nhit) val)
                              (t (setq val (if (zerop bb)
                                               (ack (1- aa) 1)
                                               (ack (1- aa) (ack aa (1- bb)))))
                                 (setf (gethash key memo) val)
                                 val)))))))
      (let ((ret (ack m n)))
        (format t "A(~d,~d)=~:d (~:d calls, ~:d cache hits)~%"
                m n ret ncal nhit)
        (values ret memo)))))

如您所见,我对较小的 a 使用了显式公式,对较大的 a 使用了内存。

但是请注意,此函数增长如此之快以致于尝试计算实际值毫无意义;你将更快地耗尽宇宙中的原子——无论是否内存。

关于scheme - 可以简化此功能(制作更多 "fast")吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20393589/

相关文章:

list - 方案列表等价比较

numbers - 计算算术 - 8 位数字需要多少位

algorithm - 讨论小 n 计算复杂度的正确方法

Emacs 方案(方案模式)缩进

scheme - 如何检查/导出/序列化(诡计)Scheme 环境

scheme - 寻找更清晰的方法来从数字列表中创建关联列表

regular-language - 需要有限自动机的正则表达式 : Even number of 1s and Even number of 0s

scheme - Ghuloum使用什么方案?

lisp 读取命令对 sbcl 工作错误

lisp - 轮盘赌选择示例的解释