Using a predicate in the filter function of "< limit and mod 2 == 0" does not work as the fibs sequence is evaluated even after the terms in the sequence become greater than the limit (all it means is that every term above the limit is filtered out). Replacing the limit check with take-while would fix this.
The third solution is also broken, it works fine for small values of n but enter a large number such as is given in the problem and you quickly run out of stack. Replacing the recursive call with recur will enable tail-call optimisation and give your stack a lot more breathing room.
I recommend the clojure-euler wiki for more reliable examples of good clojure code :)
Ha thanks for your comments spuz. Not sure what happened on #2 that I ended up posting broken code. For number #3, I don't think recur will work without changing the algorithm a bit. There are 2 recursive calls depending on the conditional, and recur needs to be last for it to compile. Also in my defense it works on my machine ;)
So, yes its a learning process. I'm updating the post. Thanks again for your comments.
I tried your solution to #3 on my old windows laptop and trying to find the prime factors for 600851475143 gave a stack overflow. However, replacing the recursive calls with recur produced the correct result. I think this is because only one of the two branches that recurse is ever executed so tail-call optimisation is still possible in this case. If it was called twice (as in some implementations of the Fibonacci sequence) I'm guessing it would fail.
This is interesting. I'd be interested to see the runtimes of these programs. It's fascinating to see how fast some of the most seemingly-complicated problems go. (It's also fun to use a programming language with unlimited-size integers, as I think Clojure has -- for an example, see problem 97. Arc just did the arithmetic in 44 milliseconds without me having to do any optimization.)
Funny, I just started a new repo for doing euler problems with clojure. I'm only on the first couple problems, but am generally pretty impressed. For the seconed problem (sum of fibonaccis), my commit message is this:
confirmed, timed at: "Elapsed time: 0.41989 msecs" -- original c solution will no longer run.
My old 32 bit machine died and the original (crappy) C solution now segfaults immediately, and was much slower.
Anyway, calculating and summing all the fibonacci numbers in less than half a millisecond is pretty cool.
The second solution will run indefinitely:
Using a predicate in the filter function of "< limit and mod 2 == 0" does not work as the fibs sequence is evaluated even after the terms in the sequence become greater than the limit (all it means is that every term above the limit is filtered out). Replacing the limit check with take-while would fix this.The third solution is also broken, it works fine for small values of n but enter a large number such as is given in the problem and you quickly run out of stack. Replacing the recursive call with recur will enable tail-call optimisation and give your stack a lot more breathing room.
I recommend the clojure-euler wiki for more reliable examples of good clojure code :)