素数判定のメモ化のために連想配列を使います。連想配列にキーが存在するかの判定は、こうすればいいようですね。
$a = @{ 2 = $true; 3 = $true; 4 = $false } $a[5] -ne $null
無いキーを参照すると$nullが返るようです。
5分弱かかりました。
function fold($f, $x0) { begin { $x = $x0 } process { $x = &$f $x $_ } end { $x } } $memo = @{ } function is_prime($n) { if($n -eq 2) { return $true } elseif($n -lt 2 -or $n % 2 -eq 0) { return $false } if($memo[$n] -ne $null) { return $memo[$n] } for($p = 3; $p * $p -le $n; $p += 2) { if($n % $p -eq 0) { $memo[$n] = $false return $false } } $memo[$n] = $true $true } function length($a, $b) { for($n = 0; ; ++$n) { if(!(is_prime (($n + $a) * $n + $b))) { return $n } } } function abs($n) { $a0 = -$n + 1 + $n % 2 for($b = 2; $b -lt $n; ++$b) { if(!(is_prime $b)) { continue } for($a = $a0; $a -lt $n; $a += 2) { ,@($a, $b) } } } function max($a, $b) { if($a[0] -lt $b[0]) { $b } else { $a } } $watch = New-Object System.Diagnostics.Stopwatch $watch.Start(); $N = 1000 abs $N | foreach { ,((length $_[0] $_[1]), ($_[0] * $_[1])) } | fold { max $args[0] $args[1] } @(0, 0) $watch.Stop(); $watch.Elapsed.TotalMilliSeconds / 1000