(defn exp-mod [base exp m]
(cond
(zero? exp) 1
(even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
:else (mod (* base (exp-mod base (inc exp) m)) m)))
(defn fermat-test [n]
(defn try-it [a]
(= (exp-mod a n n) a))
(try-it (inc (rand-int (dec n)))))
(defn fast-prime? [n times]
(cond
(zero? times) true
(fermat-test n) (recur n (dec times))
:else false))
Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use TCO?
In fact, you may want to consider reading How to Design Programs before SICP.
Can you confirm the difference between my original
defn and your letfn? Both work, but as I understand it from the
documentation, defn would actually define that local function
globally, while letfn actually does bind it locally to all the expr
which follow in the body..