私は プロジェクトオイラー 数を分解し、それを行うために次の関数を書いた問題です。
(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
もし他の人たちが示唆しているように、 when
砂 do
砂 println
s - あなたのプログラムは動作します!
いくつかの提案:
- つかいます
quot
の代わりに/
整数商を得る。 - スレッド化マクロを開始することもできます。
(->> value (Math/sqrt) ... )
. - つかいます
:else
、ない:default
それ以外の何かをキャッチオール句をあなたのcond
.