/ Обикновена линия с усложнение, основен факторинг

Обикновена цикъла с усложнение, основно факторинг

Работя по а Проект Ойлер проблем, който включва факторинг номера и са написали следната функция за това.

(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 и моите отчети са оценени по странен ред. Ето резултата от 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)) от предишния случай се оценява до вярно. Също така изходното условие се удря два пъти. Последният оценен случай трябва да бъде за n = 3, но можете да видите изход до n = 5.

Очевидно правя нещо основно погрешно, но не виждам какво. (Свързан ли е, има ли по-добър начин да се направи списък?)

Отговори:

1 за отговор № 1

Първо, има имплицитна "кога" (или "ако") в тестовата част на която и да е cond така че не трябва да използвате when себе си в този тест.

Второ, използвате единствен формуляр, a when форма, като целия клон на cond, следователно, cond не вижда втората форма, която очаква, когато тестът е вярно.

Вижте този пример за правилното cond:

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


0 за отговор № 2

Ако, както другите са ви предложили, вие изваждате всички несправедливи - whenпясък doпясък printlns - вашата програма работи!

Няколко предложения:

  • употреба quot вместо / за да получите цяло число коефициент.
  • Също така може да започнете макрото ви за теглене по следния начин: (->> value (Math/sqrt) ... ).
  • употреба :else, не :default или каквото и да е друго, за да въведете клаузата за улов във вашата cond.