NOTE: **use Perl;** is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

blazar

(email not shown publicly)

http://blazar.perlmonk.org/

**Yahoo! ID:** bik.mido (**Add User, Send Message**)

**Jabber:** blazar@jabber.org

(email not shown publicly)

http://blazar.perlmonk.org/

Friday December 01, 2006

05:55 PM

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__

Project Euler
More |
Login
| Reply

Stories, comments, journals, and other submissions on use Perl; are Copyright 1998-2006, their respective owners.

## Or work backwards (Score:1)

## Then again... (Score:1)

## Just fine (Score:1)

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 s

-- # This prints: Just another Perl hacker, seek DATA,15,0 and print q... ; __END__