Una vez que dejamos de exigir que el algoritmo de producir todas las soluciones, y la demanda de cambio que se producen de una solución, se puede utilizar un codicioso técnica para acelerar el algoritmo aún más. Asignar a los términos que empiezan con la más grande posible. Esto le da un muy rápido algoritmo que, sin embargo, no falte a ninguna de las soluciones, en el sentido de que si hay al menos uno, una solución.
Aquí es un ejemplo.
0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 10000^2 = 100000000
0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 9600^2 + 2800^2 = 100000000
0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 9984^2 + 512^2 + 240^2 = 100000000
0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 9992^2 + 392^2 + 56^2 + 56^2 = 100000000
0^2 + 0^2 + 0^2 + 0^2 + 0^2 + 9999^2 + 141^2 + 10^2 + 3^2 + 3^2 = 100000000
0^2 + 0^2 + 0^2 + 0^2 + 9999^2 + 141^2 + 10^2 + 4^2 + 1^2 + 1^2 = 100000000
0^2 + 0^2 + 0^2 + 9999^2 + 141^2 + 10^2 + 3^2 + 2^2 + 2^2 + 1^2 = 100000000
0^2 + 0^2 + 9999^2 + 141^2 + 9^2 + 5^2 + 3^2 + 1^2 + 1^2 + 1^2 = 100000000
0^2 + 9999^2 + 141^2 + 10^2 + 2^2 + 2^2 + 2^2 + 2^2 + 1^2 + 1^2 = 100000000
9999^2 + 141^2 + 10^2 + 3^2 + 2^2 + 1^2 + 1^2 + 1^2 + 1^2 + 1^2 = 100000000
Y aquí es otra.
0^3 + 0^3 + 0^3 + 0^3 + 396^3 + 312^3 + 196^3 = 100000000
0^3 + 0^3 + 0^3 + 463^3 + 79^3 + 57^3 + 41^3 = 100000000
0^3 + 0^3 + 464^3 + 46^3 + 17^3 + 7^3 + 4^3 = 100000000
0^3 + 464^3 + 46^3 + 16^3 + 10^3 + 6^3 + 2^3 = 100000000
464^3 + 46^3 + 16^3 + 9^3 + 7^3 + 5^3 + 3^3 = 100000000
Un último ejemplo.
0^5 + 39^5 + 22^5 + 21^5 + 14^5 + 3^5 + 1^5 = 100000000
37^5 + 27^5 + 27^5 + 18^5 + 8^5 + 8^5 + 5^5 = 100000000
Este es el código.
#! /usr/bin/perl -w
mi %memo;
mi @basepows;
sub powrep {
my ($n, $k, $p) = @_;
mi $clave = "$n-$k";
return $memo{$key} si existe $memo{$key};
volver [] si $k == 1;
mi @res = ();
foreach my $bpair (@basepows){
mi $bp = $bpair->[1];
siguiente si $bp >= $n;
mi $resref = powrep($n-$ta, $k-1, $p);
si(escalares(@$resref)){
push @res, [$bpair->[0], @{$resref->[0]}];
último;
}
}
$memo{$key} = \@res;
return $memo{$key};
}
PRINCIPAL: {
mi $n = shift || 1729;
mi $k = shift || 2;
mi $p = shift || 3;
mueren "todos los parámetros (n, k, p) positiva por favor"
si $n<1 || $k<1 || $p<1;
my ($p, $val) = (1);
do {
$val = $p ** $p;
if($val<=$n){
$memo{"$val-1"} = [[$p]];
push @basepows, [$p, $val];
}
$p++;
} while($val<$n);
@basepows = reverse(@basepows);
mi @allsols;
para(mi $zterms = $k-1; $zterms >= 0; $zterms--){
mi $resref = powrep($n, $k$zterms, $p);
si(escalares(@$resref)){
push @allsols, [(0) x $zterms, @{$resref->[0]}];
}
}
foreach my $sol (@allsols){
mi $check = 0;
foreach my $t (@$sol){
$cheque += $t ** $p;
}
mi @términos = map { "$_^$p" } @$sol;
imprimir join(' + ', @términos);
print "= $compruebe\n";
}
exit 0;
}