无尽的循环重现

时间:2013-03-20 23:24:21

标签: loops clojure tail-recursion

我正在学习Clojure,我刚刚开始Project Euler,我遇到了一个我无法弄清楚的问题。这是我的代码:

(defn largest_prime_factor
  [x]
  (if (prime? x) x)
  (loop [running x divider 2]
    (if (= 0 (mod running divider))
      (let [d (/ running divider)]
        (if (prime? d)
          d
          (recur d 2)))
      (recur x (inc divider)))))

(largest_prime_factor 12)  ;works
(largest_prime_factor 49)  ;works
(largest_prime_factor 147) ;Endless loop!

我意识到这可能不是找到最大素数因子的最有效方法,但我想弄清楚的是为什么它会陷入循环中。显然我正在以错误的方式使用循环重复,但我做错了什么?

2 个答案:

答案 0 :(得分:3)

(if (prime? x) x)

我认为你的意思是

(if (prime? x) x
  (loop [...

答案 1 :(得分:3)

一些事情

(defn largest_prime_factor
  [x]
  (if (prime? x) x)                 ; #1
  (loop [running x divider 2]
    (if (= 0 (mod running divider))
      (let [d (/ running divider)]
        (if (prime? d)
          d
          (recur d 2)))
      (recur x (inc divider)))))    ; #2
  1. 额外的右括号使其成为一个没有if子句的自包含else。这与无限循环没有关系,但会给出一个主要输入的错误答案(1)(除非你在1开始你的分频器,在这种情况下你可以省略这个初始测试)。

  2. 这一行应该以{{1​​}}而不是running重复出现,否则你没有考虑除数,x测试将会是假的。这就是你无限循环的原因。