Advent of Code 2023

Posted on 02 Jan 2024 in programming • 5 min read

Advent of code map

I participated in the first few days of advent of code 2023. Here are my though. Solutions are available on GitHub.

Day 1

Trebuchet!

Part 1

Simply using re.findall(r'\d',line) on each line allowed to retrieve the flag for this challenge.

Part 2

I was stuck longer on this part. My first idea was to add the literal digits to the regex. I also added a dictionary to convert the literal digit to an integer.

It seemed to work, it worked on the test sample, but the result was wrong. Looking on the adventofcode reddit someone posted that oneight should be 18. It tilted, my regex was not allowing for overlaps. I just switch to regex instead of re and allowed for overlaps to get the flag.

Day 2

Overall Day 2 was quit easy and calm.

Part 1

The first part for day2 was pretty easy, I just verified that each "grab" was respecting the constraints.

Part 2

This time we update the previous constraints dictionary if the number from the grab is higher than the previous constraints value.

Day 3

Part 1

What is a number?!

For the first part I parsed the map and for each number checked if there was a symbol in the line above or below with a range of +/-1. I also check for symbol before or after the number. Quit easy but required to load the whole schema in memory.

Part 2

What is a gear?!

We do more or less the same as in the first part, we find each start and look if there is number adjacent to it and if there is exactly two we compute the product of them.

Day 4

Part 1

The first part is easy, I divided each line and checked how much numbers were in the wining list and then compute the score. Nothing particular here.

Part 2

The second part more tricky, and I was probably tired as I did day 1 to 5 in the same day. I did a first round on each card and determined its score.

Then I did another pass on each card with two more loops to "recursively" compute the number of cards.

Day 5

The challenge required me to read it several times before understanding it. We need to follow a map to know were which seed will be planted.

Part 1

In part one there was not so much seed, so we could easily compute all the seeds and find the closest one.

Part 2

In the second part we had way more seeds and bruteforcing the result took some time. The only change to the code was the way to retrieve the initial seeds (see 751be211ed584c73ea79a29bc6ad699468b9d26d). And that failed:

python day_05_02.py
fish: Job 1, 'python day_05_02.py' terminated by signal SIGKILL (Forced quit)

So I rewrote the seed "generation" to verify if a seed is already in my table (see 1495fa869bec721cdefeaaf7678f8c4fa362dfac). This script ran for more than 9 hours without any success and I had to kill it.

Day 6

The code is the same for both part today.

Back to school! We wanted to solve a movement equation:

$$a = 1$$
$$s = at = t$$
$$d = s(T-t) = t(T-t) = Tt-t^2$$

Where:

  • \(a\) is the acceleration of 1 millimeter per square second.
  • \(v\) is the speed, which is here equal to the time we press the button \(t\).
  • \(d\) is the distance we move which is equal to the speed multiplied by the time we travel. Here the speed is the time we press the button \(t\) and the time we travel is the total time \(T\) minus the time we press the button \(t\).

Therefor, we needed to solve \(Tt-t^2 > D\) where \(T\) is the total time and \(D\) the record distance.

This was a second degree equation \(-t^2 + Tt - D = 0\) where \(t\) is the variable.

A quick math reminder:

When \(a \ne 0\), there are two solutions to \((ax^2 + bx + c = 0)\) and they are

$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$

Applied here we got the following solutions:

$$ x = {-T \pm \sqrt{T^2-4D} \over -2} $$

As we could only press the button for an integer number of second we used the math.floor and math.ceil to get integer value.

Another pitfall was when the solutions were integers. It means that pressing the button for the solutions time would result in equalling the record and not beat it.

Just computing the difference between the two solution (floored, or ceiled) would give us the result.

Day 7

Part 1

I made this problem far more complicated than it should. But I was able to get it in the end.

We have a table that match each "hand" to a "bid" and then we create a new tab that will match each hand to a score. Then we create a new table. We iterate over each hand and see where it should be put in the newest table. For that we parse the second table and see if our current hand is weaker than each one in the newest table. If it is we insert our hand there.

Part 2

For this part we changed the score attribution function and the card order. There were a few edge cases to take into account.

Day 8

Part 1

Quit easy, I used a map (a python dictionary) to "map" the path and each instruction get us to a new location. Pretty straightforward.

Part 2

I did a first version that tried to get all of them to finished at the same time. While it was computing I took a tour of the reddit and saw that it would take way too long and that using the LCM was the way to go. So I simply merge the code of the part 1 and part 2 to make a hybrid one day_08_03.py that will solve each start separately and then use math.lcm to compute the answer.

Day 9

Part 1

I did this one on Monday 11 and this was pretty standard and easy. Brace for part 2!

Part 2

Okay no, this was pretty easy.

Day 10

Part 1

A maze! We need to find the longer path. For that we need to explore all direction (north, east, west, south) and follow the loop until we get back to start. We know that only for characters change our direction ("J", "F", "L" and "7") so until we got on one of them we continue in the direction we are going. Otherwise, we use a match/case statement to ensure we go in the right direction and count our number of step.

Part 2

Nope, nope nope.