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

Problem 20


4桁ずつ区切った長整数で計算しました。各桁の和だけでなく、100!そのものも出してみました。

@echo off

setlocal enabledelayedexpansion
set /a N = 100
set /a a.size = 1
set /a a_0 = 1
for /L %%i in (1, 1, %N%) do (
    call :mul_long a %%i b
    call :copy_vector b a
)
call :print_long a
call :sum_digits a
echo %ERRORLEVEL%
exit /b 0

:sum_digits
    setlocal
    set /a s = 0
    set /a max_index = "%1.size" - 1
    for /L %%i in (0, 1, %max_index%) do (
        set /a e = "%1_%%i"
        call :sum_digits_core !e!
        set /a s += !ERRORLEVEL!
    )
    exit /b %s%

:sum_digits_core
    setlocal
    if "%1" == "" exit /b 0
    set s=%1
    call :sum_digits_core %s:~1%
    set /a n = %s:~0,1% + %ERRORLEVEL%
    exit /b %n%

:mul_long
    set /a size = "%1.size"
    set /a max_index = size - 1
    set /a carry = 0
    for /L %%i in (0, 1, %max_index%) do (
        set /a %3_%%i = "%1_%%i" * %2 + !carry!
        set /a carry = "%3_%%i" / 10000
        set /a %3_%%i %%= 10000
    )
    if %carry% == 0 (
        set /a %3.size = %size%
    ) else (
        set /a %3.size = %size% + 1
        set /a %3_%size% = %carry%
    )
    exit /b 0

:copy_vector
    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

: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 max_index = "%1.size" - 1
    for /L %%k in (0, 1, %max_index%) do (
        if %%k LSS %max_index% (
            set /a e = "%1_%%k" + 10000
            set s=!e:~1!
        ) else (
            set /a s = "%1_%%k"
        )
        set res_long_to_string=!s!!res_long_to_string!
    )
    exit /b 0