I am trying to check the following factorization function, but it explodes for large prime numbers:
(defn divides? [N n] (zero? (mod N n))) (defn f-reduce [nf & {:keys [expt] :or {expt 0}}] (if (divides? nf) (f-reduce (/ nf) f :expt (inc expt)) (if (zero? expt) [n []] [n [f expt]]))) (defn _factors [nf known-fs] (let [[m fs] (f-reduce nf)] (if (> f (Math/sqrt m)) (cond (and (empty? fs) (= m 1)) known-fs (empty? fs) (concat known-fs [m 1]) (= m 1) (concat known-fs [f (last fs)]) true (concat known-fs [m (last fs)]))
which at each recursive step tries to reduce the number n to some product p^km .
As I understand it, the trampoline is designed to solve the problem by returning the function that the trampoline then calls (returning another function), etc., the stack image looks something like this:
|fn 1| --> |fn 2| -- ... --> |fn n|
unlike irregular recursive
|fn 1| --> |fn 1|fn 2| -- .. --> |fn 1|fn 2| ... |fn nk| BOOM|
But for input for coefficients 12424242427 I get:
java.lang.StackOverflowError: null at clojure.lang.LazySeq.seq (LazySeq.java:49) clojure.lang.RT.seq (RT.java:507) clojure.core/seq (core.clj:137) clojure.core$concat$fn__4215.invoke (core.clj:691) clojure.lang.LazySeq.sval (LazySeq.java:40) clojure.lang.LazySeq.seq (LazySeq.java:49) clojure.lang.RT.seq (RT.java:507) clojure.core/seq (core.clj:137) clojure.core$concat$fn__4215.invoke (core.clj:691) clojure.lang.LazySeq.sval (LazySeq.java:40) clojure.lang.LazySeq.seq (LazySeq.java:49) clojure.lang.RT.seq (RT.java:507) clojure.core/seq (core.clj:137) clojure.core$concat$fn__4215.invoke (core.clj:691) clojure.lang.LazySeq.sval (LazySeq.java:40) clojure.lang.LazySeq.seq (LazySeq.java:49) clojure.lang.RT.seq (RT.java:507) clojure.core/seq (core.clj:137) clojure.core$concat$fn__4215.invoke (core.clj:691) clojure.lang.LazySeq.sval (LazySeq.java:40) clojure.lang.LazySeq.seq (LazySeq.java:49)
What am I missing? (I know that this algorithm is not perfect, it improves, which is completely for me)
source share