Problem 47 is a rather strange computation, because the author of the problem wanted us to bundle together multiples of a prime factor, which I found a little unusual because it means considering a prime number to an exponent as “prime”, which isn’t strictly true. Unfortunately, this additional constraint on the problem meant that rather directly use
prime-factors-of from problem 12, the prime factors needed little ‘tweak’ to use the largest multiplicity possible for each prime.
Here is the result of the tweaking:
;; From problem 12 (defn prime-factors-of "Returns a sorted list of prime factors of num, including multiplicity." [num] (let [q (Math/sqrt num) factor? (fn [nom den] (zero? (rem nom den)))] (loop [n num d 2 r ] (cond (> d q) (concat r [n]) (= n d) (concat r [n]) (factor? n d) (recur (/ n d) d (conj r d)) true (recur n (inc d) r))))) (defn tweaked-factors [factors] (let [f (frequencies (prime-factors-of factors))] (map #(* % (f %)) (keys f)))) (defn euler-47 [n] (let [groups (partition n 1 (iterate inc 2)) myfn (fn [g] (let [f (map #(tweaked-factors %) g)] (and (every? #(= n (count %)) f) (distinct? (apply concat f)))))] (first (filter myfn groups))))
Incrementally checking the return value of the function turned out to be rather useful for testing correctness:
user> (euler-47 2) (14 15) user> (euler-47 3) (644 645 646) user> (euler-47 4) (134043 134044 134045 134046)