Iterated digits squaring: Difference between revisions

→‎{{header|Perl 6}}: Replace nqp with fast algorithm example
(→‎{{header|Perl 6}}: Replace nqp with fast algorithm example)
Line 1,718:
{{out}}
<pre>85744333</pre>
Which is better, but is still pretty slow.
This runs in under ten minutes. We can reduce this significantly by writing in the NQP (Not Quite Perl6) subset of the language:
<lang perl6>use nqp;
my $cache := nqp::list_i();
nqp::bindpos_i($cache, 650, 0);
nqp::bindpos_i($cache, 1, 1);
nqp::bindpos_i($cache, 89, 89);
 
The biggest gains are often from choosing the right algorithm.
sub Euler92(int $n) {
$n < 650
?? nqp::bindpos_i($cache,$n,ids($n))
!! ids($n)
}
 
<lang perl6>sub idsendsWithOne(int $numn --> intBool) {
my int $n = $numdigit;
my int $tensum = 100;
my int $sumnn = 0$n;
myloop int $t;{
my int while ($c;nn > 0) {
repeat until $n == 89 or $ndigit == 1$nn % {10;
$sum += 0$digit²;
$nn = $nn div 10;
repeat {
$t = nqp::div_i($n, $ten); }
$c = $n - $treturn *True if $tensum == 1;
$sum = $sum + $creturn *False if $csum == 89;
} while $nnn = $tsum;
$sum = 0;
$n = nqp::atpos_i($cache,$sum) || $sum;
}
$n;
}
 
my int $cntk = 08; # 10**8
my @sums is default(0) = 1,0;
for 1 .. 100_000_000 -> int $n {
my $s;
$cnt = $cnt + 1 if Euler92($n) == 89;
for (1 .. 100_000_000$k) -> int $n {
for ($n*81 ... 1) -> $i {
for (1 .. 9) -> $j {
$s = $j²;
last if $s > $i;
@sums[$i] += @sums[$i - $s];
$n < 650 }
$n;}
}
 
say $cnt;</lang>
my $ends-with-one = sum flat @sums[(1 .. $k*81).grep: { endsWithOne($_) }], +endsWithOne(10**$k);
 
say 10**$k - $ends-with-one;</lang>
 
{{out}}
<pre>85744333</pre>
 
=={{header|Phix}}==
10,333

edits