非过剩数之和
作者:Shlomi Fish
http://projecteuler.net/problem=23
如果一个数的所有真因数之和等于它本身,则该数被称为完全数。例如,28 的真因数之和为 1 + 2 + 4 + 7 + 14 = 28,这意味着 28 是一个完全数。
如果一个数 n 的所有真因数之和小于 n,则该数被称为亏数;如果该和大于 n,则该数被称为过剩数。
由于 12 是最小的过剩数,1 + 2 + 3 + 4 + 6 = 16,因此可以写成两个过剩数之和的最小数字是 24。通过数学分析,可以证明所有大于 28123 的整数都可以写成两个过剩数之和。然而,即使已知不能表示为两个过剩数之和的最大数小于此上限,但通过分析也无法进一步降低此上限。
求所有不能写成两个过剩数之和的正整数之和。
use v6; my @divisors_sums; @divisors_sums[1] = 0; my $MAX = 28_123; for (1 .. ($MAX +> 1)) -> $div { loop (my $prod = ($div +< 1); $prod <= $MAX; $prod += $div) { @divisors_sums[$prod] += $div; } } # Memoized. # my @is_abundant_sum; my @abundants; my $total = 0; for (1 .. $MAX) -> $num { if @divisors_sums[$num] > $num { @abundants.push($num); # The sub { ... } and return are a workaround for the fact that Rakudo # Perl 6 does not have last LABEL yet. my $c = sub { for @abundants -> $i { if ((my $s = $i + $num) > $MAX) { return; } else { if (! @is_abundant_sum[$s]) { $total += $s; @is_abundant_sum[$s] = True; } } } }; $c(); } } say ((((1 + $MAX) * $MAX) +> 1)-$total);