平方数字链

作者:Moritz Lenz

https://projecteuler.net/problem=92

数字链的创建方式是:不断将数字的各个位数的平方相加,形成一个新的数字,直到出现重复的数字为止。

例如:

44 → 32 → 13 → 10 → Pod::FormattingCode<94304298579360> → Pod::FormattingCode<94304298579296>
85 → Pod::FormattingCode<94304298579232> → 145 → 42 → 20 → 4 → 16 → 37 → 58 → Pod::FormattingCode<94304298579168>

因此,任何到达 1 或 89 的链都将陷入无限循环。最令人惊讶的是,每个起始数字最终都会到达 1 或 89。

在小于一千万的起始数字中,有多少个数字最终会到达 89?

源代码: prob092-moritz.pl

use v6;

unless @*ARGS {
    say 'WARNING';
    say 'This is going to take *really* long (order of magnitude: 30 h) with';
    say 'the default number (1e7)';
    say 'To run it for a small number, simply supply that number';
    say 'on the command line.';
}

my %ser;
%ser{1}  = 1;
%ser{89} = 89;

my @squares = map { $_ * $_ }, 0..9;

sub ser($i is copy) {
    return %ser{$i} if %ser{$i}:exists;
    my @to_update;
    while !(%ser{$i}:exists) {
        @to_update.push($i);
        $i = [+] $i.split('').map: { $_ * $_ };
    }
    my $s = %ser{$i};
    %ser{$_} = $s for @to_update;
    return $s;
}

my $c = 0;
my $target = @*ARGS[0] // 1e7;
say "running up to $target";
for 1..($target-1) {
    .say if $_ % ($target / 10).Int == 0;
    ++$c if ser($_) == 89;
}
say "Result: $c";