2013-03-20 101 views
2

我正在學習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! 

我知道這可能不是找到最大的主要因素,但我想要搞清楚的是爲什麼它陷在一個循環的最有效的方式。很明顯,我使用循環錯誤的方式,但我做錯了什麼?

回答

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. 該行應重複使用running而不是x,否則您沒有考慮除數和prime?測試將永遠是錯誤的。這就是爲什麼你在無限循環中結束。

+0

謝謝。我太在意另一個問題了 – DPA 2013-03-21 09:04:35

3
(if (prime? x) x) 

我想你的意思

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