PDA

View Full Version : Advent of Code, 2024 - Day 02



Petr Schreiber
19-12-2024, 10:44
Hi,

I would like to share a possible solution for day 2 of Advent of Code 2024.

SPOILERS BELOW

The assignment can be found at https://adventofcode.com/2024/day/2
Please note that to reach the assignment you need to complete the assignment 1 (https://www.thinbasic.com/community/showthread.php?13371-Advent-of-Code-2024-Day-01) first.

Please make sure you download your input.txt file from the page above and that you pass it as parameter to the scripts below (for example in thinAir, you enter input.txt to Script/Command line... if you stored the file side by side with the solutions)

Part 1

Here we are supplied with a file full of sequences and we need to find those which go in one direction (ascending, descending) and with allowed difference between two numbers in sequence being limited.

uses "console", "file"


function tbmain()
string inputFile = app.ArgV(2)

if not file_exists(inputFile) then
printl inputFile
printl "Please specify valid input file as first parameter of the script"
waitkey
return 1
end if

string inputContent = file_load(inputFile)

string lines()
long entryCount = parse(inputContent, lines, $LF) - 1 ' Last line left empty

long i
long sequenceRating, safeCount
string description
for i = 1 to entryCount
' Printing the analysed line + extra space to space out later rating
print lset$(lines(i), 32 using " ")

sequenceRating = GetSequenceRating(lines(i), description)

if sequenceRating = 0 Then
incr safeCount
end if

' Optional explanation of sequence rating
printl description in iif(sequenceRating = 0, 10, 12)

next

printl
printl safeCount, "safe items" in 14

waitkey
end function


function GetSequenceRating(sequenceText as string, byref description as string) as long
long j, originalDirection, direction, diff
long values()
long valueCount = split(sequenceText, " ", values)

for j = 2 to valueCount
diff = values(j) - values(j-1)
direction = sgn(diff)

if j = 2 then
if diff = 0 Then
description = "UNSAFE - no direction"
return 1
end if

originalDirection = direction
end if

if direction <> originalDirection Then
description = "UNSAFE - inconsistent direction"
return 2
end if

if not between(abs(diff), 1, 3) Then
description = "UNSAFE - too big gap"
return 3
end if

if j = valueCount then
description = "SAFE"
return 0
end if
next

end function


Part 2

The second part spices up the assignment by the possibility of making the sequence valid after removal of one element.

uses "console", "file"


function tbmain()
string inputFile = app.ArgV(2)

if not file_exists(inputFile) then
printl inputFile
printl "Please specify valid input file as first parameter of the script"
waitkey
return 1
end if

string inputContent = file_load(inputFile)

string lines()
long entryCount = parse(inputContent, lines, $LF) - 1 ' Last line left empty

long i, j
long sequenceRating, safeCount
string description, alteredSequence
for i = 1 to entryCount
' Printing the analysed line + extra space to space out later rating
print lset$(lines(i), 32 using " ")

sequenceRating = GetSequenceRating(lines(i), description)

if sequenceRating = 0 Then
incr safeCount
else
' The original form is not valid, let's alter it by removing specific element
for j = 1 to parsecount(lines(i), " ")
alteredSequence = GetSequenceWithoutNthElement(lines(i), j)
if GetSequenceRating(alteredSequence, description) = 0 Then
incr safeCount
exit for
end if
next
end if

' Optional explanation of sequence rating
printl description in iif(sequenceRating = 0, 10, 12)

next

printl
printl safeCount, "safe items" in 14

waitkey
end function


function GetSequenceRating(sequenceText as string, byref description as string) as long
long j, originalDirection, direction, diff
long values()
long valueCount = split(sequenceText, " ", values)

for j = 2 to valueCount
diff = values(j) - values(j-1)
direction = sgn(diff)

if j = 2 then
if diff = 0 Then
description = "UNSAFE - no direction"
return 1
end if

originalDirection = direction
end if

if direction <> originalDirection Then
description = "UNSAFE - inconsistent direction"
return 2
end if

if not between(abs(diff), 1, 3) Then
description = "UNSAFE - too big gap"
return 3
end if

if j = valueCount then
description = "SAFE"
return 0
end if
next

end function

function GetSequenceWithoutNthElement(sequenceText as string, n as long) as string
return trimfull$(ParseSet$(sequenceText, " ", n, ""))
end function



Petr

Lionheart008
19-12-2024, 17:50
Hello Petr doesn't Work Here your both examples or I am too stupid for IT :-)
"Please specify valid Input File AS First Parameter of the Script" ???
Regards frank

Petr Schreiber
19-12-2024, 21:28
Hi Frank,

thanks for stopping by!

You need to launch the script with input file as parameter. Each Advent of Code challenge has specific input for each person.

If you go to:
- https://adventofcode.com/2024
- Log In via preffered way

...you can start the Advent of Code challenge yourself and download the input from the challenge assignment. It is a simple text file.

Then, in thinAir, you can go to Script / Command line to supply path to the puzzle input.

Note: You need to start with day 1 (https://www.thinbasic.com/community/showthread.php?13371-Advent-of-Code-2024-Day-01) to unlock day 2.


Petr

ErosOlmi
24-12-2024, 10:56
Thanks a lot Petr.

Using your Part 1 example I've implemented PARSE function to be able to parse using line and field delimiters also for numeric matrix.
In next thinBasic version it will be possible to script the following to load numbers into a numeric matrix:

'---Load lines into a matrix of strings of entryCount and 2 columns
long Data() '---<---LONG Matrix, before only string matrix was allowed
long entryCount = parse(inputContent, Data, $CRLF, " ")
printl $"Number of lines..: {ubound(Data(1)}"
printl $"Number of columns: {ubound(Data(2)}"



Before it was possible only for string matrix.

Now I'm working to load string columns into single separated arrays as an option.
So you successive parsing of left/right part will not be necessary
Something like the following syntax will load separated arrays in one go:

long leftList()
long rightList()
long entryCount = parse(inputContent, (leftList, rightList) , $CRLF, " ")

Petr Schreiber
30-12-2024, 16:24
Ho ho hoo,

that will be awesome, thank you :drink:


Petr