我觉得最好的方法不是嵌套而是预先计算。查看我们使用零进行测试的基本情况:
(mystery 0 2) ; ==> 2
(nystery 3 0) ; ==> 3
因此,每次至少一个参数为零时,它都会返回另一个参数。让我们尝试使用一个非零值,并记住第二秒你看到我们已经完成的值,然后再用它的结果切换它:
(mystery 1 3) ; ==
(+ 2 (mystery 0 2)) ; == (we switch known value)
(+ 2 2)
; ==> 4
(mystery 4 1) ; == (we substitute with the expression)
(+ 2 (mystery 3 0)) ; == (we switch known value)
(+ 2 3)
; ==> 5
因为我们知道基本情况总是返回另一个值,我们不需要预先计算它。这是这样做的:
(mystery 3 9) ; == (we substitute with the expression)
(+ 2 (mystery 2 8) ; == (we substitute with the expression)
(+ 2 (+ 2 (mystery 1 7))) ; == (we substitute with the expression)
(+ 2 (+ 2 (+ 2 (mystery 0 6))) ; == (we substitute with the expression, n, which is 6)
(+ 2 (+ 2 (+ 2 6))) ; == (we substitute (+ 2 6))
(+ 2 (+ 2 8)) ; == (we substitute (+ 2 8))
(+ 2 10) ; == (we substitute (+ 2 10)
; ==> 12
我们可以概括会发生什么。 n 和 m 中的最低值将决定递归何时结束。在每一步,它将添加 2 并递归。因此这是一种奇特的制作方式:
(define (double-min n m)
(let ((vmin (min n m))
(vmax (max n m)))
(+ (* 2 vmin) (- vmax vmin))))
这又是一种将两个数字相加的奇特方式,因为如果n > m,那么2*m+(n-m) = m+m+(n-m) = m+n