1 2 3 4 5 6 …
の偶数を2で割って、
1 1 3 2 5 3 …
隣同士を掛け合わせると、
1 3 6 10 15 …
これは三角数の列になっています。2番目の列の約数の数を求めると、
1 1 2 2 2 2 …
隣同士を掛け合わせて、
1 2 4 4 4 …
これが対応する三角数の約数の数になっています(2番目の列の隣同士は互いに素だから)。こうすれば速く計算できます。これで20分でした。
@echo off call :get_time set /a t0 = %ERRORLEVEL% set /a L = 500 set /a n = 2 set /a prev_num = 1 :loop set /a r = %n% %% 2 if %r% == 0 ( set /a m = %n% / 2 ) else ( set /a m = %n% ) call :num_divs %m% set /a num = %ERRORLEVEL% set /a mul_num = %prev_num% * %num% set /a n += 1 set /a prev_num = %num% if %mul_num% LSS %L% goto :loop set /a nt = (%n% - 2) * (%n% - 1) / 2 echo %nt% call :get_time set /a t = %ERRORLEVEL% - %t0% echo %t:~0,-2%.%t:~-2%s exit /b 0 :num_divs setlocal set /a num = 1 set /a n = %1 set /a p = 2 :loop_num_divs set /a e = 0 :loop_num_divs2 set /a r = %n% %% %p% if %r% == 0 ( set /a e += 1 set /a n /= %p% goto :loop_num_divs2 ) set /a num *= %e% + 1 if %n% == 1 exit /b %num% set /a p += 1 set /a p_sq = %p% * %p% if %n% GEQ %p_sq% goto :loop_num_divs set /a num *= 2 exit /b %num% :get_time setlocal set t=%TIME% set /a h = %t:~0,2% set /a m = 1%t:~3,2% %% 100 set /a s = 1%t:~6,2% %% 100 set /a ss = 1%t:~-2% %% 100 set /a ret = ((%h% * 60 + %m%) * 60 + %s%) * 100 + %ss% exit /b %ret%