エラトステネスのふるい的に約数の和を求めるだけですね。
function fold($f, $x0) { begin { $x = $x0 } process { $x = &$f $x $_ } end { $x } } function div_pow($n, $d) { $e = 0 while($n % $d -eq 0) { ++$e $n /= $d } ($e, $n) } function sum_divs($n) { $a = 0..$n $b = $a | foreach { 1 } foreach($p in 2..$n) { if($p * $p -gt $n) { break } elseif($a[$p] -eq $p) { for($k = $p; $k -le $n; $k += $p) { $e, $a[$k] = div_pow $a[$k] $p $b[$k] *= (1..$e | fold { $args[0] * $p + 1 } 1) } } } foreach($k in 2..$n) { if($a[$k] -ne 1) { $b[$k] *= $a[$k] + 1 } } 0..$n | foreach { $b[$_] - $_ } } function gen_amicables($n) { $d = sum_divs $n foreach($k in 2..$n) { $m = $d[$k] if($m -lt $k -and $d[$m] -eq $k) { $k, $m } } } (gen_amicables 10000 | measure -sum).sum