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

Problem 15


40C20を求めるだけの問題ですが、答えが32ビットを超えるから問題になるのです。
ここではパスカルの三角形を使います。そうすると加算だけで答えが求められます。10進で8桁ずつに区切って配列にして計算すればよいでしょう。

@echo off

setlocal
set /a N = 40
set /a M = %N% / 2
set /a C0_0.size = 1
set /a C0_0_0 = 1
for /L %%i in (1, 1, %N%) do (
    for /L %%j in (0, 1, %%i) do (
        call :calc_C %%i %%j
    )
)
call :print_long C%N%_%M%
exit /b 0

:calc_C
    if %2 == 0 call :copy_long C0_0 C%1_%2 & exit /b 0
    if %2 == %1 call :copy_long C0_0 C%1_%2 & exit /b 0
    set /a n_1 = %1 - 1
    set /a m_1 = %2 - 1
    call :copy_long C%n_1%_%m_1% C%1_%2
    call :add_long C%1_%2 C%n_1%_%2
    exit /b 0

rem // %1を%2に
:copy_long
    set /a %2.size = "%1.size"
    set /a max_index = %1.size - 1
    for /L %%i in (0, 1, %max_index%) do set /a %2_%%i = "%1_%%i"
    exit /b 0

:add_long
    set /a size1 = "%1.size"
    set /a size2 = "%2.size"
    call :max %size1% %size2%
    set /a size = %ERRORLEVEL%
    set /a %1.size = %size%
    set /a k = 0
    :loop_add_long
        set /a %1_%k% += "%2_%k%"
        set /a e = "%1_%k%"
        set /a k_1 = %k% + 1
        if %e% GTR 100000000 (
            set /a %1_%k% -= 100000000
            set /a %1_%k_1% += 1
        )
        set /a k += 1
        if %k% LSS %size% goto loop_add_long
    
    set /a e = "%1_%k%"
    if %e% GTR 0 set /a %1.size = %k% + 1
    exit /b 0

:print_long
    call :long_to_string %1
    echo %res_long_to_string%
    exit /b 0

:long_to_string
    set res_long_to_string=
    set /a size = "%1.size"
    set /a k = 0
    :loop_long_to_string
        set /a e = "%1_%k%"
        set res_long_to_string=%e%%res_long_to_string%
        set /a k += 1
        if %k% LSS %size% goto :loop_long_to_string
    exit /b 0

:max
    if %1 GTR %2 exit /b %1
    exit /b %2

:push_vector
    set /a size = "%1.size"
    set /a %1_%size% = %2
    set /a %1.size += 1
    exit /b 0