Inspired by
S. Lott and his
blog post (and by the pure genius that
xkcd is giving us these days,
today included) I gave a look to
Project Euler problem 14, that's about the
Collatz conjecture.
The straightforward recursive solution:
def collatz(n):
if n == 1:
return 1
if n % 2 == 0:
return 1 + collatz(n/2)
else:
return 1 + collatz(3*n + 1)
very rapidly converges to... an error:
RuntimeError: maximum recursion depth exceeded
So I've recoded it a bit using a
cache dictionary to store all the intermediate values in it:
cache = {1: 1}
def collatz(n, res):
nn = n
while True:
if n in cache:
if nn != n:
cache[nn] = cache[n]
return cache[nn]
if n % 2 == 0:
cache[n] = 1 + collatz(n/2, cache)
else:
cache[n] = 1 + collatz(3*n + 1, cache)
Now loping for all the numbers lower than 1 million we find the solution to the problem: the number with the longest path is 837799 with a path length of 524. The code runs in about 4secs.
Since I got that
cache dict around to play with, I graphed with Matplotlib (strange, ha ;) ) the frequencies of each path length:

There are few short paths, several long paths but rare to occur, and most of the paths have length between 100 and 200 (more or less).
UPDATE: I've removed
length variable, not needed (left from a previous version of the code) and fixed the path length for 837799, wrongly reported.