Here we go then, the 1st day of 2023’s Advent of Code.
Day 1 looked deceptively simple, with part 1 completed in pretty quick time. The only real problem was the large amount of data caused memory overflow issues, so I split it into 4 separate parts for the data statements.
I’ll list some code segments with explanation on how I did it below, but I don’t want to post the answers for this current year on here for obvious reasons.
First off, declaring the variables:
I used two subroutines to do the number crunching. It’s not very complicated, this one is used to find the left most number. It’s first set to 100 so we have a benchmark to compare against later on. It then simply loops through each character based on the length of the string and compares it to a digit.
LN (Left Number) is set to a multiple of 10 to satisfy the problem – so if 3 is found first, it needs to be set to 30 as we want to add the single last digit of the string to it. i.e. if the last digit found is 5 then the value for this line would be 35.
Once a left number is found, the loop obviously needs to exit to prevent it finding any more numbers – so we exit as soon as LN is less than 100 (i.e. any of the other values).
SUB FINDNUMSL (TEST$ AS STRING * 96) STATIC
L=LEN(TEST$)
LN = 100 'set to an unfindable value - only required for LN
FOR I=0 TO L-1
M=MID$(TEST$, I, 1)
' Test for left numeric only
IF M="0" THEN
LN=0
END IF
IF M="1" THEN
LN=10
END IF
IF M="2" THEN
LN=20
END IF
IF M="3" THEN
LN=30
END IF
IF M="4" THEN
LN=40
END IF
IF M="5" THEN
LN=50
END IF
IF M="6" THEN
LN=60
END IF
IF M="7" THEN
LN=70
END IF
IF M="8" THEN
LN=80
END IF
IF M="9" THEN
LN=90
END IF
IF LN < 100 THEN ' We need to exit the loop as soon as a numeric is found
EXIT FOR
END IF
NEXT I
' Left most digit found
' End subroutine
END SUB
The subroutine for the right most number, imaginatively called FINDNUMSR, is almost identical except for 2 differences. We set RN to the single digit as opposed to a multiple of 10, as that will be added to LN, and we don’t exit the loop, meaning we keep going until the end so that RN holds the last value in that string.
With the SUBS setup it’s just a matter of cycling through each input line, calling them both, and totalling up the values as we go.
And as I said, I did this 3 more times for the other 750 lines of data, which yes is a bit cheaty but then XC=BASIC makes me lazy.
Part 2 was trickier as we had to find actual strings of digits that would take precedent over the digits themselves, so if the string looked something like ‘iuskjnineij5hkjlcnd6slkj8klmsstwo‘ the result we want is 92.
To accomplish this I just did more of the same and added extra logic into both subroutines, again exiting the loop early for the left number and letting it complete for the right number.
'Part 2
IF M = "o" AND MID$(TEST$,I+1,1) = "n" AND MID$(TEST$,I+2,1) = "e" THEN
LN=10
END IF
IF M = "t" AND MID$(TEST$,I+1,1) = "w" AND MID$(TEST$,I+2,1) = "o" THEN
LN=20
END IF
IF M = "t" AND MID$(TEST$,I+1,1) = "h" AND MID$(TEST$,I+2,1) = "r" AND MID$(TEST$,I+3,1) = "e" AND MID$(TEST$,I+4,1) = "e" THEN
LN=30
END IF
IF M = "f" AND MID$(TEST$,I+1,1) = "o" AND MID$(TEST$,I+2,1) = "u" AND MID$(TEST$,I+3,1) = "r" THEN
LN=40
END IF
IF M = "f" AND MID$(TEST$,I+1,1) = "i" AND MID$(TEST$,I+2,1) = "v" AND MID$(TEST$,I+3,1) = "e" THEN
LN=50
END IF
IF M = "s" AND MID$(TEST$,I+1,1) = "i" AND MID$(TEST$,I+2,1) = "x" THEN
LN=60
END IF
IF M = "s" AND MID$(TEST$,I+1,1) = "e" AND MID$(TEST$,I+2,1) = "v" AND MID$(TEST$,I+3,1) = "e" AND MID$(TEST$,I+4,1) = "n" THEN
LN=70
END IF
IF M = "e" AND MID$(TEST$,I+1,1) = "i" AND MID$(TEST$,I+2,1) = "g" AND MID$(TEST$,I+3,1) = "h" AND MID$(TEST$,I+4,1) = "t" THEN
LN=80
END IF
IF M = "n" AND MID$(TEST$,I+1,1) = "i" AND MID$(TEST$,I+2,1) = "n" AND MID$(TEST$,I+3,1) = "e" THEN
LN=90
END IF
' End of part 2
The total run time, for both part 1 and part 2 in the same script was 12 minutes 56 seconds.
This screen shows just 1 part completing – there were 3 more after this and I totalled up the output for my answers.