Skip to content

Instantly share code, notes, and snippets.

@fvh-P
Last active February 14, 2018 00:46
Show Gist options
  • Save fvh-P/6d8acddc0b0907369effac65ccd3386a to your computer and use it in GitHub Desktop.
Save fvh-P/6d8acddc0b0907369effac65ccd3386a to your computer and use it in GitHub Desktop.
Quick Sort
@echo off
choice /n /m "ログを取得しますか?(Y/N)"
if %errorlevel% == 1 call :echoon
if %errorlevel% == 2 call :Main
:echoon
@echo on
call :Main > qs.log 2>&1
:Main
setlocal enabledelayedexpansion
del /q %cd%\before.txt
del /q %cd%\after.txt
call :GetNoe noe count
if "%noe%" == "" exit
if %noe% lss 1 exit
call :SetArray arr %noe%
call :Shuffle arr %noe% %count%
for /l %%i in (1,1,%noe%) do echo !arr[%%i]!>>before.txt
echo シャッフル完了。ソート前の状態をbefore.txtに出力しました。
echo 何かキーを押すとソート開始。
pause >nul
call :GetStartTime
call :qsort arr :IntegerComparison 1 %noe%
call :GetEndTime
for /l %%i in (1,1,%noe%) do echo !arr[%%i]!>>after.txt
echo ソート完了。ソート後の状態をafter.txtに出力しました。
call :PutTime
pause
exit
:GetNoe::ref noe, ref count -> void
set /p %1="要素数を1以上の整数(半角)で入力。3000以上にしないことををお勧めします。0以下または入力なしで終了。 >"
set /p %2="要素を並び替えるための入れ替え回数を指定。要素数の1.3倍以上が適切です。 >"
exit /b
:SetArray::ref arr, int noe -> void
for /l %%i in (1,1,%2) do (
set %1[%%i]=%%i
)
exit /b
:Shuffle::ref arr, int noe, int count -> void
for /l %%i in (1,1,%3) do (
set /a sel1=!random!*%2/32768+1
set /a sel2=!random!*%2/32768+1
set /a tmp=%1[!sel1!],%1[!sel1!]=%1[!sel2!],%1[!sel2!]=tmp
)
exit /b
:IntegerComparison::int a, int b -> int
setlocal
set /a tmp=%1-%2
exit /b %tmp%
:qsort::ref arr, func cmp(<T> a, <T> b -> int), int left, int right -> void
set /a left=%3,right=%4
if %left% geq %right% (
exit /b
)
set /a i=%left%,j=%right%,y=i+(j-i)/2
call :med3 !%1[%i%]! !%1[%y%]! !%1[%j%]!
set pivot=%errorlevel%
:while1
:while2
call %2 !%1[%i%]! %pivot%
if %errorlevel% lss 0 (
set /a i+=1
goto while2
)
:while3
call %2 %pivot% !%1[%j%]!
if %errorlevel% lss 0 (
set /a j-=1
goto while3
)
if %i% lss %j% (
set /a tmp=%1[%i%],%1[%i%]=%1[%j%],%1[%j%]=tmp,i+=1,j-=1
goto while1
)
set /a i-=1,j+=1
call :qsort %1 %2 %3 %i%
call :qsort %1 %2 %j% %4
exit /b
:med3::int x, int y, int z -> int
if %1 lss %2 (
if %2 lss %3 (
exit /b %2
) else if %3 lss %1 (
exit /b %1
) else (
exit /b %3
)
) else if %3 lss %2 (
exit /b %2
) else if %1 lss %3 (
exit /b %1
) else (
exit /b %3
)
echo エラー
exit
:GetStartTime
set T=%TIME: =0%
set H=%T:~0,2%
set M=%T:~3,2%
set S=%T:~6,2%
set C=%T:~9,2%
rem --8進対策
set /a H=1%H%-100,M=1%M%-100,S=1%S%-100,C=1%C%-100
exit /b 0
:GetEndTime
set T1=%TIME: =0%
set H1=%T1:~0,2%
set M1=%T1:~3,2%
set S1=%T1:~6,2%
set C1=%T1:~9,2%
rem --8進対策
set /a H1=1%H1%-100,M1=1%M1%-100,S1=1%S1%-100,C1=1%C1%-100
rem --終了時間の計算
set /a H2=H1-H,M2=M1-M
if %M2% LSS 0 set /a H2=H2-1,M2=M2+60
set /a S2=S1-S
if %S2% LSS 0 set /a M2=M2-1,S2=S2+60
set /a C2=C1-C
if %C2% LSS 0 set /a S2=S2-1,C2=C2+100
if %C2% LSS 10 set C2=0%C2%
exit /b 0
:PutTime
echo.
echo 開始時間:%T%
echo 終了時間:%T1%
echo 経過時間:%H2%h %M2%m %S2%.%C2%sec
exit /b 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment