The code below finds 1..10 in 2 seconds on this machine, having calculated nothing greater than 201!; 1..37 takes 8s, and calculates 366!. Beyond that we start to find some more difficult, but at 37 mins and 24MB it has so far found all but 8 numbers (59, 64, 72, 86, 87, 92, 97, 99) out of 1..99.
Update: still missing (92, 97, 99) after 274 mins (process size 67MB).
The basic ideas are: a) keep a sorted list (@try) of the numbers we've reached but not yet calculated a factorial for; b) at each iteration, take the smallest untried number and find it's factorial, and repeatedly take the square root of the result until we get to a number we've seen before; c) use a binary chop to insert new pending numbers.
#!/usr/bin/perl use strict; use bigint; # optionally with eg C< lib => 'Pari' > my $max = shift || 10; my @try; # deal with '1' explicitly my %seen = (1 => 's'); my $waiting = $max - 1; print "1 => s\n"; insert(3, ''); while (@try) { my $n = shift @try; my $s = 'f' . $seen{$n}; $n->bfac; # $n = ($n)! $s = "f$s"; while (!defined $seen{$n}) { insert($n, $s); $n = sqrt($n); $s = "s$s"; } } sub insert { my($n, $s) = @_; if ($n <= $max) { print "$n => $s\n"; exit 0 unless --$waiting; } $seen{$n} = $s; my($min, $max) = (0, scalar @try); while ($min + 1 < $max) { my $new = ($min + $max) >> 1; if ($try[$new] > $n) { $max = $new; } else { $min = $new; } } ++$min if $min < @try && $try[$min] < $n; splice @try, $min, 0, $n; }
In the output, eg "5 => ssff" means that 5 = int(sqrt(int(sqrt(fact(fact(3)))))).
Hugo
In reply to Re: Challenge: Chasing Knuth's Conjecture
by hv
in thread Challenge: Chasing Knuth's Conjecture
by kvale
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |