最初の一つだけほしいのでnextという関数を考えます。filterを使って、
filter next() { $_ break }
1個値を受け取ってそれを排出して、そのあとなんらかの方法で例外を投げます。ここではbreakしています。ここで終わってもいいですが、そのあとコードを動かすには例外処理をします。PowerShellの例外処理はC++などとは違います。どこでもいいのでtrap文を書き、そこでcontinueとすると処理の流れが例外発生箇所の次へ行きます。
function fold($f, $init) {
begin { $x = $init }
process { $x = & $f $x $_ }
end { $x }
}
filter next() {
$_
break
}
function digits($n) {
while($n -gt 0) {
$d = $n % 10
$d
$n = ($n - $d) / 10
}
}
function is_palindromic($n) {
$m = digits $n | fold { $args[0] * 10 + $args[1] } 0
$m -eq $n
}
function products($n) {
function put($a, $b) {
if(-not $c.contains($a)) {
$c.Add($a, $b)
}
}
$c = New-Object System.Collections.SortedList
$m = $n - 1
$c.Add((-$m * $m), @($m, $m))
while($true) {
-$c.GetKey(0)
$a, $b = $c.GetByIndex(0)
$c.RemoveAt(0)
if($a -eq $b) {
put (-($a - 1) * ($a - 1)) @(($a - 1), ($a - 1))
}
put (-$a * ($b - 1)) @($a, ($b - 1))
}
}
$n = 1000
products $n | where { is_palindromic $_ } | next
trap { continue }