Skip to content

Instantly share code, notes, and snippets.

@GolezTrol
Created December 8, 2023 15:18
Show Gist options
  • Save GolezTrol/3435ffe8ae023d3951d41401d106aedf to your computer and use it in GitHub Desktop.
Save GolezTrol/3435ffe8ae023d3951d41401d106aedf to your computer and use it in GitHub Desktop.
Advent of code 2023 day 7 Camel Cards (Windows Batch file)
@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