in reply to Challenge: Chasing Knuth's Conjecture
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
|
---|
Replies are listed 'Best First'. | |
---|---|
Re^2: Challenge: Chasing Knuth's Conjecture
by tall_man (Parson) on Mar 29, 2005 at 17:44 UTC | |
by hv (Prior) on Mar 29, 2005 at 19:10 UTC | |
Re^2: Challenge: Chasing Knuth's Conjecture
by Roy Johnson (Monsignor) on Mar 29, 2005 at 17:55 UTC | |
by tall_man (Parson) on Mar 29, 2005 at 20:07 UTC | |
by Roy Johnson (Monsignor) on Mar 30, 2005 at 01:19 UTC |