コラッツに戻りましょう。この問題も1に辿りつくまでに何回同じ操作を繰り返せばよいかわかりません。以下では、70回繰り返して、その間に1に辿りつかなかったらまた70回繰り返す、というフローにしています。
また、6の倍数で場合わけをしています。例えば、5余る場合、6n+5 ← 12n+10 ← 4n+3となるので、これより小さくて2つ長い数があります。つまり5余る場合は考えなくてよいことになります。それから長さを求めるときに4で割ったときの余りを考えると速くなります。例えば、余りが3のとき4n+3 → 12n+10 → 6n+5 → 18n+16 → 9n+8と4つ進めることができます。
これでも1時間半かかってしまいました。もう少しくらいは速くなりそうですが、1時間は切れそうにないです。
@echo off setlocal enabledelayedexpansion call :start_time set /a N = 1000000 set /a half = %N% / 2 set /a delta = 70 set /a s = 0 for /L %%i in (%half%, 1, %N%) do ( call :Collatz %%i if !ERRORLEVEL! GTR !s! ( set /a s = !ERRORLEVEL! set /a max_n = %%i ) ) echo %max_n% call :check_time exit /b 0 :Collatz setlocal set /a r = %1 %% 6 if %r% GEQ 4 exit /b 0 if %r% == 2 exit /b 0 set /a m = %1 set /a begin = 1 set /a end = %delta% set /a k = 0 :loop_Collatz for /L %%k in (%begin%, 1, %end%) do ( if !m! LEQ 2 ( set /a k += !m! exit /b !k! ) set /a r = !m! %% 4 if !r! == 0 ( set /a m /= 4 set /a k += 2 ) else ( if !r! == 3 ( set /a m = !m! / 4 * 9 + 8 set /a k += 4 ) else ( set /a m = !m! / 4 * 3 + !r! set /a k += 3 ) ) ) set /a begin += %delta% set /a end += %delta% goto :loop_Collatz :start_time call :get_time set /a __t0 = %ERRORLEVEL% exit /b 0 :check_time setlocal call :get_time set /a t = %ERRORLEVEL% - %__t0% if %t% LSS 10 ( echo 0.0%t%s ) else ( if %t% LSS 100 ( echo 0.%t%s ) else ( echo %t:~0,-2%.%t:~-2%s ) ) exit /b 0 :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%