After my last review request, I decided to try and make a "tree" visualization, and thought that I could benefit from making find-prime-factors
lazily produce prime factors so the visualization can be updated in real time as factors are found.
This is what I ended up with. I was actually surprised how easy it was to adapt the loop
to a recursive lazy-seq
solution. The non-return accumulators were added as parameters to a recursive function, and the lazy return list was created via the typical (lazy-seq (cons ... ...))
. It actually performs identically to the previous strict version too when evaluation is forced using vec
.
If anyone sees anything here that can be commented on, I'd like to know.
(doseq [p (lazily-find-prime-factors 99930610001)]
(println p
(int (/ (System/currentTimeMillis) 1000))))
163 1544998649
191 1544998692
3209797 1544998692
Same as in the last review:
(ns irrelevant.prime-factorization.prime-factorization)
(defn is-factor-of? [n multiple]
(zero? (rem n multiple)))
(defn prime? [n]
(or (= n 2) ; TODO: Eww
(->> (range 2 (inc (Math/sqrt ^double n)))
(some #(is-factor-of? n %))
(not))))
(defn primes []
(->> (range)
(drop 2) ; Lower bound of 2 for the range
(filter prime?)))
(defn smallest-factor-of? [n possible-multiples]
(some #(when (is-factor-of? n %) %)
possible-multiples))
Updated:
(defn lazily-find-prime-factors [n]
(letfn [(rec [remaining remaining-primes]
(when-let [small-prime (and (> remaining 1)
(smallest-factor-of? remaining remaining-primes))]
(lazy-seq
(cons small-prime
(rec (long (/ remaining small-prime))
(drop-while #(not= % small-prime) remaining-primes))))))]
(rec n (primes))))