I've recently joined Project Euler. For the moment when I have some spare time I check the problems in order and try to solve them. Actually none of those I've seen thus far is particularly challenging either mathematically or algorithmically. (But I'm seeing them in supposed ascending order of difficulty.) Now I've just solved Problem 14, which is the first interesting one. Not that it was terribly challenging either, but it was... well, interesting. And fun to code.
Here's the statement of the problem:
The following iterative sequence is defined for the set of positive integers:
n -> n/2 (n is even)
n -> 3n + 1(n is odd)Using the rule above and starting with 13, we generate the following sequence:
13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
And here's my code:
#!/usr/bin/perl -l use strict; use warnings; use constant MAX => 1_000_000; my ($seen,@memz)=0; sub coll { my $n=my $m=shift; return 0 if vec($seen,$n,1); my $i=0; while ($n>1) { return $memz[$m]=$i+$memz[$n] if $memz[$n]; vec($seen,$n,1)=1 if $n < MAX; $n = $n%2 ? 3*$n+1 : $n/2; $i++; } $memz[$m]=$i; } my ($max,$maxv)=0; for (2..MAX) { my $new=coll($_) or next; ($max,$maxv)=($new,$_) if $new > $max; } print $maxv; __END__
Then again...
runrig on 2006-12-02T02:07:24
Eh, it was just an idea.Just fine
blazar on 2006-12-02T08:16:09
Indeed: a reverse algorithm is interesting too. The idea must have blinked in my mind for a few microseconds as well, but then I realized that brute force could become very very lightweight provided one were careful enough to use already done calculations to avoid doing unnecessary ones: experimentation proved that my intuition was right, since the program pasted here gave me the answer in about 20 seconds, which is fine. Although I'm not really sure whether one should call that brute force any more. On a second thought I lean towards the hypothesis that one should not...