Windows PowerShellでProject Euler(19)

Problem 13

この問題は1桁ずつの配列にして足し合わせます。足すときPythonのizip_longestに相当する関数を用意しておくとコーディングが比較的楽になります。

$s = "37107287533902102798797998220837590246510135740250",
    ...,
    "53503534226472524250874054075591789781264330331690"

function fold($f, $init) {
    begin   { $x = $init }
    process { $x = & $f $x $_ }
    end     { $x }
}

function izip_longest($a, $b, $default) {
    $n1 = $a.length
    $n2 = $b.length
    foreach($k in 0..(([math]::max($n1, $n2) - 1))) {
        if($k -lt $n1) {
            if($k -lt $n2) {
                ,($a[$k], $b[$k])
            }
            else {
                ,($a[$k], $default)
            }
        }
        else {
            ,($default, $b[$k])
        }
    }
}

function reverse($a) {
    $n = $a.length
    foreach($k in 1..$n) {
        $a[$n-$k]
    }
}

function todigits($s) {
    $n = $s.length
    0..($n-1) | foreach { [int]$s.substring($_, 1) }
}

function add_long($a, $b) {
    $c = 0
    foreach($x in (izip_longest $a $b)) {
        ($p, $q) = $x
        $s = $p + $q + $c
        if($s -lt 10) {
            $s
            $c = 0
        }
        else {
            $s - 10
            $c = 1
        }
    }
    if($c -eq 1) { $c }
}

$ds = $s | foreach { ,(todigits $_) } | foreach { ,(reverse $_) } |
                    fold { add_long $args[0] $args[1] } (,0)
-join $ds[-1..-10]