Clojure Tail Recursion с основными факторами

Я пытаюсь научить себя закрытию и использую принципы Prime Factors Kata и TDD для этого.

Посредством серии тестов Midje, подобных этому:

(fact (primefactors 1) => (list))

(fact (primefactors 2) => (list 2))

(fact (primefactors 3) => (list 3))

(fact (primefactors 4) => (list 2 2))

Я смог создать следующую функцию:

(defn primefactors 
    ([n] (primefactors n 2))
    ([n candidate] 
        (cond (<= n 1) (list)
              (= 0 (rem n candidate)) (conj (primefactors (/ n candidate)) candidate)
              :else (primefactors n (inc candidate))
        )
    )
)

Это отлично работает, пока я не использую следующий тест крайнего случая:

(fact (primefactors 1000001) => (list 101 9901))

I заканчиваются ошибкой переполнения стека. Я знаю, что мне нужно превратить это в правильные циклы повторения, но все примеры, которые я вижу, кажутся слишком упрощенными и указывают только на счетчик или числовую переменную в качестве фокуса. Как мне сделать это рекурсивным ?

Спасибо!

6
задан omiel 2 December 2013 в 10:47
поделиться