素因数分解がなかなかうまくいきません。配列の配列を一つ関数から出すと、配列の配列になってくれません。仕方がないので、配列の要素の型を調べてInt32だったら配列の配列にします。
function fold($f, $init) {
begin { $x = $init }
process { $x = & $f $x $_ }
end { $x }
}
filter next() {
$_
break
}
function pow($n, $e) {
if($e -eq 0) {
1
}
else {
$n * (pow $n ($e - 1))
}
}
function div_pow($n, $d) {
$e = 0
while($n % $d -eq 0) {
++$e
$n /= $d
}
$e, $n
}
function factorize($n) {
function f($n, $p0) {
if($n -gt 1) {
for($p = $p0; $p * $p -le $n; ++$p) {
if($n % $p -eq 0) {
$e, $m = div_pow $n $p
,@($p, $e)
f $m ($p + 1)
return
}
}
,($n, 1)
}
}
$fs = f $n 2
if($fs[0].GetType().Name -eq "Int32") {
,(,$fs)
}
else {
$fs
}
}
function value_f($fs) {
$fs | fold { $args[0] * (pow $args[1][0] $args[1][1]) } 1
}
filter half_f() {
if($_[0] -eq 2) {
if($_[1] -gt 1) {
,@($_[0], ($_[1] - 1))
}
}
else {
,$_
}
}
function triangle() {
$prev_fs = @(,(3, 1))
for($n = 4; ; ++$n) {
$fs = factorize $n
,($prev_fs + $fs | half_f)
$prev_fs = $fs
}
}
function num_divs($fs) {
$fs | fold { $args[0] * ($args[1][1] + 1) } 1
}
$N = 500
triangle | foreach { ,((value_f $_), (num_divs $_)) } |
where { $_[1] -gt $N } | foreach { $_[0] } | next
trap { continue }