Göran Weinholt wrote:
> I should have mentioned this explicitly: it goes a lot higher than
> k=39: A(k=10000)=-19928164276191803466..[lots of numbers]..96034899
> This was computed in milliseconds.
My perl version takes a few seconds, but I got the same results for
k=10K. :-)
>
> Let me show you the code in a different language (unfortunately
> neither assembler nor PL/I). The C code below is like my R6RS Scheme
> code, except it does neither memoization nor bignums, so it will be
> slower and will give the wrong result at higher k values. Call
> A(31,1,-1,-1,1,0) to compute A(k=31). Hopefully this is easier to
> read. The algorithm is, as previously noted, due to Knuth.
Thanks for the code, it was trivial to translate into a memoizing bignum
perl version:
#!perl -w
use strict;
use bignum;
my @c1 = (0,0,0,1,2,3);
sub c1
{
my ($k) = @_;
$c1[$k] = c1($k - 1) + c2($k - 1) unless (defined($c1[$k]));
return $c1[$k];
}
my @c2 = (0,0,1,1,1,2);
sub c2
{
my ($k) = @_;
$c2[$k] = c2($k - 1) + c3($k - 1) unless (defined($c2[$k]));
return $c2[$k];
}
my @c3 = (0,1,1,0,0,1);
sub c3
{
my ($k) = @_;
$c3[$k] = c3($k - 1) + c4($k) unless (defined($c3[$k]));
return $c3[$k];
}
my @c4 = (1,1,0,0,0,0);
sub c4
{
my ($k) = @_;
$c4[$k] = c1($k - 1) + c4($k-1) - 1 unless (defined($c4[$k]));
return $c4[$k];
}
sub c5
{
my ($k) = @_;
return $k ? 1 : 0;
}
sub A
{
my ($k, $x1, $x2, $x3, $x4, $x5) = @_;
return c1($k) * $x1 + c2($k) * $x2 + c3($k) * $x3 +
c4($k) * $x4 + c5($k) * $x5;
}
my $max = shift;
if (defined($max)) {
my $mob = 1;
# Initialize the memoization tables by calls to every 20th value,
# this limits the recursion depth:
for (my $i = 0; $i < $max; $i += 20) {
$mob = A($i,1,-1,-1,1,0);
}
printf("%3d %40s\n", $max, A($max,1,-1,-1,1,0));
}
else { # No input parameter, so print all the values up to 100:
for (my $i = 0; $i <= 100; $i++) {
printf("%3d %40s\n", $i, A($i,1,-1,-1,1,0));