Skip to content

Instantly share code, notes, and snippets.

@unclebob
Created October 18, 2010 14:34
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unclebob/632303 to your computer and use it in GitHub Desktop.
Save unclebob/632303 to your computer and use it in GitHub Desktop.
Prime factors Kata in Clojure
(ns prime-factors-test
(:use clojure.test midje.sweet))
(defn factors-starting-at [f n]
(cond
(> f (Math/sqrt n)) (if (= n 1) [] [n])
(= 0 (mod n f)) (cons f (factors-starting-at f (/ n f)))
:else (recur (inc f) n)))
(defn prime-factors-of [n]
(factors-starting-at 2 n))
(defn mersenne [n]
(int (dec (Math/pow 2 n))))
(deftest prime-factors
(fact (prime-factors-of 1) => [])
(fact (prime-factors-of 2) => [2])
(fact (prime-factors-of 3) => [3])
(fact (prime-factors-of 4) => [2 2])
(fact (prime-factors-of 5) => [5])
(fact (prime-factors-of 6) => [2 3])
(fact (prime-factors-of 7) => [7])
(fact (prime-factors-of 8) => [2 2 2])
(fact (prime-factors-of 9) => [3 3])
(fact (prime-factors-of 10) => [2 5])
(fact (prime-factors-of 12) => [2 2 3])
(fact (prime-factors-of 18) => [2 3 3])
(fact (prime-factors-of 25) => [5 5])
(fact (prime-factors-of 1369) => [37 37])
(fact (prime-factors-of (* 2 3 5 7 11 17 37)) => [2 3 5 7 11 17 37])
(fact (prime-factors-of (mersenne 17)) => [(mersenne 17)])
(fact (prime-factors-of (mersenne 19)) => [(mersenne 19)])
(fact (prime-factors-of (mersenne 31)) => [(mersenne 31)])
)
(run-tests)
@marvinthepa
Copy link

@hoodja: although it might seem strange when seen from a curly-brace-language-background, lispers like to put all closing parens on a single line (they feel lonely otherwise):

(defn prime-factors-of
  ([n] (prime-factors-of 2 n))
  ([f n]
    (if (> n 1)
      (if (= 0 (mod n f))
        (cons f (prime-factors-of f (/ n f)))
        (recur (inc f) n))
      [])))

I replaced () by [] to make the empty list stand out more clearly from all those parens.

To repeat my comment from above: (zero? num) is more readable than (= 0 num) IMHO, and it also has performance benefits (nice combo).

@unclebob:
I think that you really need an extra (accumulator) argument to make the function tail-recursive. But I'd be delighted if you can prove me wrong!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment