/ / Clojureループ、cond-clojure、プライムファクタリング

コンクロージャー、素因数分解を伴うClojureループ

私は プロジェクトオイラー 数を分解し、それを行うために次の関数を書いた問題です。

(defn get-factors [value]
(let [max-factor (->> (Math/sqrt value)
(Math/floor)
(Math/round))
ifactors #{}]
(loop [n 2 factors ifactors]
(do
(println (format ">> N: %d, Factors: %s" n factors))
(cond
(when (> n max-factor)   ; exit of we have passed the max-factor
(do
(println (format "--Exiting(%d): %s" n factors))
factors))               ; return factors
(when (= 0 (mod value n)); have we found a factor?
(do
(println (format"--Factor(%d)" n))
(recur (inc n) (conj factors n (/ value n)))))   ; recurse: add _n_ and reciprocal _n_ to list
:default (do             ; otherwise
(println (format"--default(%d): %s" n (= 0 (mod value n))))
(recur (inc n) factors)) ; recurse: increment _n_, dont modify factors
)))))

しかし、関数は戻っています nil 私のprintlnステートメントは奇妙な順序で評価されます。 REPLからの出力は次のとおりです。 (get-factors 12)、それは返すべきです #{2,3,4,6}

>> N: 2, Factors: #{}
--default(2): true
>> N: 3, Factors: #{}
--default(3): true
>> N: 4, Factors: #{}
--Exiting(4): #{}
--Factor(4)
>> N: 5, Factors: #{3 4}
--Exiting(5): #{3 4}

ご覧のように、デフォルトの状態は (= 0 (mod value n)) 前の場合の評価は真である。同様に、終了条件は2回ヒットします。評価された最後のケースはn = 3でなければなりませんが、n = 5までの出力を見ることができます。

私は明らかに何か根本的に間違っていますが、私は何も見ていません。(関連して、リストを作成するより良い方法がありますか?)

回答:

回答№1は1

まず、テストの一部に暗黙の「when」(または「if」)があります。 cond あなたは使用しないでください when そのテストの中であなた自身。

次に、あなたは単一のフォームを使用しています。 when フォーム、全体の支店として condしたがって、 cond テストが真のときに期待している2番目のフォームは表示されません。

この適切な例を見てください cond

http://clojuredocs.org/clojure_core/1.2.0/clojure.core/cond


回答№2の場合は0

もし他の人たちが示唆しているように、 whendoprintlns - あなたのプログラムは動作します!

いくつかの提案:

  • つかいます quot の代わりに / 整数商を得る。
  • スレッド化マクロを開始することもできます。 (->> value (Math/sqrt) ... ).
  • つかいます :else、ない :default それ以外の何かをキャッチオール句をあなたの cond.