1ならoneなので長さ3、2ならtwoなので長さ3、3ならthreeなので長さ5などというのを連想配列にしておきたいところです。Pythonなら、
L = { 1: 3, 2: 3, 3: 5, ... }
などとします。しかし、これだとすぐにバグが発生しそうです。そこで、
s = { 1: "one", 2: "two", 3: "three", ... }
として、定義して長さを計算するほうが比較的バグが発生しにくいでしょう。
しかし、バッチファイルにはこのようなリテラルはありません。そこで、
call :set_length 1 one 2 two 3 three 4 four 5 five 6 six
と書いて、まず%2の長さを調べてL%1に格納します。そしてshiftを2回して同じことを繰り返します。
このようにして基本の数の長さを調べておけば、複合的な数も簡単に再帰で求められます。
@echo off setlocal enabledelayedexpansion set /a N = 1000 call :set_length 1 one 2 two 3 three 4 four 5 five 6 six call :set_length 7 seven 8 eight 9 nine 10 ten 11 eleven call :set_length 12 twelve 13 thirteen 14 fourteen call :set_length 15 fifteen 16 sixteen 17 seventeen call :set_length 18 eighteen 19 nineteen 20 twenty call :set_length 30 thirty 40 forty 50 fifty 60 sixty call :set_length 70 seventy 80 eighty 90 ninety call :set_length 100 hundred 1000 thousand set /a s = 0 for /L %%i in (1, 1, %N%) do ( call :sum_length %%i set /a s += !ERRORLEVEL! ) echo %s% exit /b 0 :sum_length setlocal if %1 == 0 exit /b 0 if %1 LEQ 20 ( set /a n = "L%1" exit /b !n! ) if %1 LSS 100 ( set /a r = %1 %% 10 set /a m = %1 - !r! call :sum_length !r! set /a n = !ERRORLEVEL! + "L!m!" exit /b !n! ) if %1 LSS 1000 ( set /a r = %1 %% 100 set /a d = %1 / 100 if !r! GTR 0 ( call :sum_length !r! set /a n = "L!d!" + %L100% + 3 + !ERRORLEVEL! ) else ( set /a n = "L!d!" + %L100% ) exit /b !n! ) if %1 == 1000 ( set /a n = %L1% + %L1000% exit /b !n! ) exit /b 0 :set_length :loop_set_length if "%1" == "" exit /b 0 call :length %2 set /a L%1 = %ERRORLEVEL% shift shift goto :loop_set_length :length setlocal if "%1" == "" exit /b 0 set s=%1 call :length %s:~1% set /a m = 1 + %ERRORLEVEL% exit /b %m%