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!

これは最大の素因数を見つけるための最も効率的な方法ではないかもしれませんが、私が理解しようとしているのは、なぜそれがループに陥るのかということです。明らかに私はloop-recurを間違った方法で使用していますが、何が間違っているのでしょうか?

4

2 に答える 2

3
(if (prime? x) x)

私はあなたが意味すると思います

(if (prime? x) x
  (loop [...
于 2013-03-20T23:40:16.610 に答える
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?テストは常に偽になります。これが、無限ループに陥る理由です。

于 2013-03-21T01:08:24.127 に答える