Skip to content

Instantly share code, notes, and snippets.

@zolrath
Created August 29, 2011 05:56
Show Gist options
  • Save zolrath/1177848 to your computer and use it in GitHub Desktop.
Save zolrath/1177848 to your computer and use it in GitHub Desktop.
Clojure 1.2.1 vs 1.3.0-beta2 Question
;; This takes about 1.7 seconds in Clojure 1.2.1 and takes 10 times as long in 1.3.0-beta2
;; Also, I'm learning Clojure so ignore the generally horrible code.
;; Tried switching to lazy-seqs prime to see if that narrowed the gap. It's a bit slower, but the gap is still there!
;; Clojure 1.2.1
(time (solve21))
"Elapsed time: 2333.739 msecs"
31626
;; Clojure 1.3.0-beta2
(time (solve21))
"Elapsed time: 17352.799 msecs"
31626
(defn amicable? [a]
"Returns true if given numbers divisors produce an amicable number"
(let [b (sum-divisors a)]
(and (not= a b) (= a (sum-divisors b)))))
(defn amicablepairs [limit]
"Returns list of all amicable pairs up to given limit"
(filter amicable? (range 2 limit)))
(defn solve21 []
(reduce + (amicablepairs 10000)))
;; Was told the old primes-to function could be to blame, switching to clojure.contrib.lazy-seqs prime generator
(defn lazy-primes-to [n]
(take-while #(< % n) primes))
(defn prime-factors-of [num]
"Returns the prime factors of a given number."
(loop [a (lazy-primes-to (inc (/ num 2)))
number num
factorlist '()]
(if (seq a)
(if (zero? (mod number (first a)))
(recur a (/ number (first a)) (conj factorlist (first a)))
(recur (rest a) number factorlist))
factorlist)))
(defn sum-divisors [num]
"Returns sum of Proper Divisors (not including number itself)"
(let [prime-factors (partition-by identity (prime-factors-of num))]
(let [sum (reduce * (map #(if (> (count %) 1)
(-> (first %) (expt (inc (count %))) (dec) (/ (dec (first %))))
(inc (first %)))
prime-factors))]
(if (= sum 1) 1 (- sum num)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment