この問題は、10001番目の素数を求めるというのがミソです。だからエラトステネスのふるいをいくつまですればいいのかわかりません。ここは手抜きをします。N = 10001として、N log2 Nまでふるいにかけることにします。ちょっと大きめですが、これでOKとします。素数定理に出てくる自然対数ではなく2を底にしているのは計算が簡単だからです。
:log2 setlocal if %1% == 1 exit /b 0 set /a n = "%1 >> 1" call :log2 %n% set /a m = %ERRORLEVEL% + 1 exit /b %m%
ビット演算は上のように引用符でくくります。それは記号が他の用途とかぶるからでしょう。
これでN番目の求めることができます。
しかし、下のコードはなぜか遅くて帰ってきませんでした。
@echo off echo %TIME% set /a N = 10001 call :get_time set /a t = %ERRORLEVEL% call :log2 %N% set /a M = %N% * %ERRORLEVEL% set /a a.size = %M% + 1 call :fill_vector a 1 call :sieve a %M% call :n_th a %N% echo %ERRORLEVEL% call :get_time set /a t = %ERRORLEVEL% - %t% echo %t:~0,-2%.%t:~-2%s exit /b 0 :sieve set sieve_v=%1 set /a max_n = %2 set /a sieve_k = 1 :loop_sieve set /a sieve_k += 1 set /a sq_sieve_k = %sieve_k% * %sieve_k% if %sq_sieve_k% GTR %max_n% exit /b 0 set /a is_prime = "a_%sieve_k%" if %is_prime% == 0 goto :loop_sieve set /a twice_k = %sieve_k% * 2 for /L %%i in (%twice_k%, %sieve_k%, %max_n%) do ( set /a a_%%i = 0 ) goto :loop_sieve :n_th setlocal set /a counter = 0 set /a k = 2 :loop_n_th set /a e = "%1_%k%" if %e% == 1 set /a counter += 1 if %counter% == %2 exit /b %k% set /a k += 1 goto :loop_n_th :log2 setlocal if %1% == 1 exit /b 0 set /a n = "%1 >> 1" call :log2 %n% set /a m = %ERRORLEVEL% + 1 exit /b %m% :fill_vector set /a max_index = "%1.size" - 1 for /L %%i in (0, 1, %max_index%) do set /a %1_%%i = %2 exit /b 0 :print_vector setlocal set vector=%1 set /a size = "%vector%.size" echo %size% if %size% == 0 echo %2 & exit /b 0 set /a e = "%vector%_0" set s=%e% set /a k = 1 :loop_print_vector if %k% == %size% echo %s% & exit /b 0 set /a e = "%vector%_%k%" set s=%s% %e% set /a k += 1 goto :loop_print_vector :get_time setlocal set t=%TIME% set /a h = 1%t:~0,2% %% 100 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%