Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Exploring Clojure with Factorials

Avatar for Noah Zucker Noah Zucker
September 19, 2012

Exploring Clojure with Factorials

Presentation to Clojure NYC meetup , Sept 2012

Avatar for Noah Zucker

Noah Zucker

September 19, 2012

Other Decks in Programming

Transcript

  1. public static int calculate(int n) { if(n == 1) return

    1; int result = 1; for (int i = n; i > 1; i--) { result *= i; } return result; }
  2. public static int calculateRecursively(int n) { if(n == 0) return

    1; return (n * calculateRecursively(n - 1)); }
  3. (defn factorial-using-recur [n] (loop [current n next (dec current) total

    1] (if (> current 1) (recur next (dec next) (* total current)) total)))
  4. user=> (def fac-expr (cons '* (range 1 6))) #'user/fac-expr user=>

    fac-expr (* 1 2 3 4 5) user=> (eval fac-expr) 120
  5. public class Factorial implements ValueComputer<Integer> { private final int; private

    Factorial(int n) { this.n = n; } public Integer compute() { return calculate(n); } }
  6. public static class Builder { private int n; public Builder

    factorial(int n) { this.n = n; return this; } public Factorial build() { return new Factorial(n); } }
  7. user=> (clojure.walk/macroexpand-all '(-> (Factorial$Builder.) (.factorial 5) .build .compute)) (. (.

    (. (new Factorial$Builder) factorial 5) build) compute) Equivalent: (.compute (.build (.factorial (new Factorial$Builder) 5))))
  8. (defn factorial-using-ref-dosync [n psz] (let [result (ref 1) parts (partition-all

    psz (range 1 (inc n))) tasks (for [p parts] (future (Thread/sleep (rand-int 10)) (dosync (alter result #(apply * % p)))))] (dorun (map deref tasks)) @result))
  9. (defn factorial-using-agent [n psz] (let [result (agent 1) parts (partition-all

    psz (range 1 (inc n)))] (doseq [p parts] (send result #(apply * % p))) (await result) @result))
  10. (defn factorial-using-pmap-reduce [n psz] (let [parts (partition-all psz (range 1

    (inc n))) sub-factorial-fn #(apply * %)] (reduce * (pmap sub-factorial-fn parts))))
  11. (declare facseq) (defn factorial-using-lazy-seq [n] (nth (facseq) n)) (defn- facseq

    ([] (facseq 1 1)) ([n v] (let [next-n (inc n) next-v (* n v)] (cons v (lazy-seq (facseq next-n next-v))))))
  12. (defmethod factorial-using-multimethods true ([limit] (factorial-using-multimethods limit (new Factorial 1 1)))

    ([limit fac] (let [next-factorial (-> fac (update-in [:n] inc) (update-in [:value] #(* % (:n fac))))] (factorial-using-multimethods limit next-factorial)))
  13. (defn factorial-for-trampoline [n] (letfn [(next-fac-value [limit current-step previous-value] (let [next-value

    (* current-step previous-value)] (if (= limit current-step) next-value #(next-fac-n limit current-step next-value)))) (next-fac-n [limit previous-step current-value] #(next-fac-value limit (inc previous-step) current-value))] (next-fac-value n 1 1)))
  14. (defn factorial-using-areduce [n] (let [arr (long-array n)] (dotimes [i n]

    (aset-long arr i (inc i))) (areduce arr idx ret (long 1) (* ret (aget arr idx)))))
  15. Don't Do This! (defn factorial-using-do-while [n] (do (def a 0)

    (def res 1) (while (< a n) (def a (inc a)) (def res (* res a))) res))