これは重複組合せを生成する問題です。PowerShellの関数はほぼジェネレータなので、簡単に生成できます。
22秒かかりました。
PowerShellのシリーズはここまでです。
function fold($f, $x0) { begin { $x = $x0 } process { $x = &$f $x $_ } end { $x } } function pow($n, $e) { return 1..$e | fold { $args[0] * $n } 1 } function digits($n) { while($n -gt 0) { $r = $n % 10 $r $n = ($n - $r) / 10 } } function number($a) { $a | fold { $args[0] * 10 + $args[1] } 0 } function repeated_combinations($a, $n) { if($n -eq 1) { $a } else { foreach($k in 0..($a.length-1)) { $e = $a[$k] repeated_combinations $a[$k..($a.length-1)] ($n - 1) | foreach { ,(@($e) + $_) } } } } function calc_limit($E) { for($n = 1; $n * $pows[9] -ge (pow 10 $n); ++$n) { } $n } function sum_pows($a) { ($a | foreach { $pows[$_] } | measure -sum).sum } function sort_by_digits($n) { number (digits $n | sort) } function matches($a) { $m = number $a $n = sort_by_digits (sum_pows $_) $m -eq $n } $watch = New-Object System.Diagnostics.Stopwatch $watch.Start(); $E = 5 $pows = 0..9 | foreach { pow $_ $E } $L = calc_limit $E (repeated_combinations (0..9) $L | where { matches $_ } | foreach { sum_pows $_ } | measure -sum).sum - 1 $watch.Stop(); $watch.Elapsed.TotalMilliSeconds / 1000