Created
December 8, 2023 15:18
-
-
Save GolezTrol/3435ffe8ae023d3951d41401d106aedf to your computer and use it in GitHub Desktop.
Advent of code 2023 day 7 Camel Cards (Windows Batch file)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
REM script calls itself with 'sethandtype' to calculate the hand type for a batch of hands. | |
REM A batch consists of a series of 'hands and bids, all space separated | |
if "%1"=="sethandtype" ( | |
:item | |
call :sethandtype %3 %4 | |
shift /3 & shift /3 | |
if not "%3"=="" goto :item | |
REM echo Thread %2 done | |
exit & REM without /b, because this is a separate process | |
) | |
setlocal EnableDelayedExpansion | |
set starttime=%time% | |
if "%1"=="" ( REM "Documentation" | |
echo Call %~0 [inputfile] | |
exit /b | |
) | |
set file=%1 | |
REM clear and create two folders for storing the files | |
if exist day7part1/nul rmdir /q /s day7part1 | |
if exist day7part2/nul rmdir /q /s day7part2 | |
md day7part1 | |
md day7part2 | |
REM Calculating the hand types is the hardest bit, so read the file into batches, and fire a separate process | |
REM for calculating the types for a batch of hands. Too many makes it slower, but 20 - 30 separate processes seems okay. | |
set handcount=0 | |
set hands= | |
set batch=0 | |
set batchsize=40 | |
echo Reading and categorizing hands | |
for /f "tokens=1,2 delims= " %%a in (%1) do ( | |
set hands=!hands! %%a %%b | |
set /a batch+=1 | |
if !batch! equ !batchsize! ( REM Batch size.. Play around to finetune | |
start "Thread !handcount!" /b "%~0" sethandtype !handcount! !hands! | |
set batch=0 | |
set hands= | |
if !batchsize! gtr 20 set /a "batchsize-=2" & REM Each next batch a little bit smaller, to aim and have them done around the same time | |
) | |
set /a handcount+=1 | |
set /a n=handcount %% 37 | |
if !n! equ 0 <nul set /p =.. !handcount! | |
) | |
if not "!hands!"=="" start "Thread !handcount!" /b "%~0" sethandtype !handcount! !hands! | |
echo. | |
echo %handcount% hands read. | |
call :sortandcount day7part1 part1 | |
call :sortandcount day7part2 part2 | |
echo part1: %part1% | |
echo part2: %part2% | |
echo Started: %starttime% | |
echo Ended: %time% | |
exit /b | |
:sortandcount foldername resultvar | |
echo calculating %2 | |
REM Separate processes are generating the files representing the hands and bids. Wait until there are enough files. | |
:sortandcount_wait | |
set "count=0" & for %%c in (%1\*) do set /a count+=1 | |
if %count% lss !handcount! ( | |
echo Got %count% files.. Waiting for %handcount% | |
timeout /t 1 /nobreak > nul | |
goto sortandcount_wait | |
) | |
REM Use the power of DIR to sort the files | |
set %2=0 | |
set rank=1 | |
for /f "usebackq tokens=1,2 delims= " %%f in (`dir /b /on "%~1"`) do ( | |
set /a %2+=!rank!*%%g | |
set /a rank+=1 | |
) | |
exit /b | |
:sethandtype hand bid | |
setlocal EnableDelayedExpansion | |
for /l %%c in (2,1,14) do set count[%%c]=0 | |
for /l %%c in (0,1,5) do set groupsof[%%c]=0 | |
REM Convert to a hexadecimal number | |
set hand=%1 | |
set hand=!hand:A=E! | |
set hand=!hand:K=D! | |
set hand=!hand:Q=C! | |
set hand=!hand:J=B! | |
set hand=!hand:T=A! | |
REM Count how many cards of the same time. While counting, count groups of a certain size | |
for /l %%c in (0,1,4) do ( | |
set /a cardnr=0x!hand:~%%c,1! | |
set /a count[!cardnr!]+=1 | |
set /a c=count[!cardnr!] | |
REM echo checking card !hand:~%%c,1! = !cardnr!. I now have !c! of those | |
for /l %%g in (1,1,5) do if !c! equ %%g set /a "lg=%%g-1" & set /a "groupsof[!lg!]-=1" & set /a "groupsof[%%g]+=1" | |
) | |
REM set /a "distinct=0-groupsof[0]" & REM isn't this nice :D Too bad we don't need it | |
REM determine the type | |
set handtype=1 | |
if %groupsof[2]% equ 1 set handtype=2 | |
if %groupsof[2]% equ 2 set handtype=3 | |
if %groupsof[3]% equ 1 set handtype=4 | |
if %groupsof[3]% equ 1 if !groupsof[2]! equ 1 set handtype=6 | |
if %groupsof[4]% equ 1 set handtype=7 | |
if %groupsof[5]% equ 1 set handtype=8 | |
REM For part 2, Do Joker magic, but remember Joker = B, 11 | |
set hand2=%hand:B=1% | |
set jokercount=!count[11]! | |
set nonjokercount=0 | |
for /l %%c in (2,1,14) do if %%c neq 11 if !count[%%c]! gtr !nonjokercount! set nonjokercount=!count[%%c]! | |
set /a combined=!jokercount!+!nonjokercount! | |
set handtype2=!handtype! | |
if %handtype% equ 1 if !jokercount! equ 1 set "handtype2=2" & REM a single becomes a pair | |
if %handtype% equ 3 if !jokercount! equ 1 set "handtype2=6" & REM two pair becomes a full house | |
if %handtype% equ 2 if !jokercount! geq 1 set "handtype2=4" & REM a pair becomes three | |
if !combined! equ 4 set handtype2=7 | |
if !combined! equ 5 set handtype2=8 | |
REM Create the two files, with "hand bid" as their filename | |
echo.>"day7part1\%handtype%%hand% %2" | |
echo.>"day7part2\%handtype2%%hand2% %2" | |
exit /b & REM back to top, because it handles batches |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment