バッチファイルでProject Euler(15)

Problem 6

高階関数

Pythonだとこんな感じに書けます。

from itertools import imap

N = 100
s = sum(xrange(1, N + 1))
s2 = sum(imap(lambda n: n * n, xrange(1, N + 1)))
print s * s - s2

sumはreduceを使えば、

N = 100
s = reduce(lambda x, y: x + y, xrange(1, N + 1), 0)
s2 = reduce(lambda x, y: x + y * y, xrange(1, N + 1), 0)
print s * s - s2

これを真似できないでしょうか。
reduceを第2引数をfirst、第3引数をlastとする関数と考えます。

:reduce
    setlocal
    set f=%1
    set /a first = %2
    set /a last = %3
    set /a init = %4
    if %first% == %last% exit /b %init%
    
    call :%f% %init% %first%
    set /a next = %first% + 1
    call :reduce %f% %next% %last% %ERRORLEVEL%
    exit /b %ERRORLEVEL%

ここで、第1引数は関数のラベルを指定します。これで引数の関数を呼び出すことができます。関数を引数にしているのではなくあくまでラベルを渡しているだけで高階関数というわけではないですが。

@echo off

set /a N = 100
set /a M = %N% + 1
call :reduce add 1 %M% 0
set /a s = %ERRORLEVEL%
call :reduce add_sq 1 %M% 0
set /a s2 = %ERRORLEVEL%
set /a result = %s% * %s% - %s2%
echo %result%
exit /b 0

:add
    setlocal
    set /a s = %1 + %2
    exit /b %s%

:add_sq
    setlocal
    set /a s = %1 + %2 * %2
    exit /b %s%

:reduce
    setlocal
    set f=%1
    set /a first = %2
    set /a last = %3
    set /a init = %4
    if %first% == %last% exit /b %init%
    
    call :%f% %init% %first%
    set /a next = %first% + 1
    call :reduce %f% %next% %last% %ERRORLEVEL%
    exit /b %ERRORLEVEL%