The world’s leading publication for data science, AI, and ML professionals.

I’m Doing the Advent of Code 2024 in Python - Day 1

Let's see how many stars we'll collect.

Photo by Nong on Unsplash
Photo by Nong on Unsplash

Advent of Code is a set of 25 programming puzzles released between December 1st and 25th of every year. Eric Wastl, inspired by the Advent Calendar, has been organizing the Advent Of Code since 2015.

This is my first year doing it and I completed the first 4 puzzles. I decided to write a blog post for each puzzle explaining my approach and solution to the problem.

As I heard and read from others who participated in Advent of Code before, it gets really difficult after the 15th puzzle (often earlier).

So I’m not sure if I’ll be able to reach the end but I’ll try my best. In any case, it’ll be a great practice on Data Structures and algorithms. It’s also a lot of fun solving puzzles and collecting stars.

The puzzles can be solved using any programming language. I’ll be using Python because 1) I’m mostly using Python at work (my other option is R) and 2) I can reach a broader audience with Python.

One last thing before I start: My solution might not be the best or most efficient one. If you know a better solution or have any suggestions to improve mine, please share in the comments.

As of writing this article, the first 6 puzzles have been released and each puzzle has two parts. I’ve completed both parts of the first puzzle and the first parts of the second, third, and fourth puzzles. Each part counts as one star. Let’s see how many stars we’ll collect.

My current progress on Advent of Code 2024 (image by author)
My current progress on Advent of Code 2024 (image by author)

Day 1 – Part 1

In the puzzle for day 1, we’re given two lists (left and right).

In the first part, we’re asked to find the difference between the smallest number in the left list and the smallest number in the right list, do the same for the second-smallest numbers, third ones, and so on. The final answer is the sum of all these differences.

It’s not directly asking the difference but saying "how far apart the two numbers" so we need to find the absolute value of the difference (i.e. (2–4) and (4–2) are the same).

The drawing below demonstrates the solution for 3-item lists:

(image by author)
(image by author)

The inputs for puzzles are different for each user. Once you open up a puzzle and you need to click on "get your puzzle input" to see your input. You can either copy the input from there or use the requests library to get it directly to your script.

You can use the get_puzzle_input function below but you need to get your own session cookie to be able to retrieve the puzzle input.

Note: It’s always best to save your session cookie as an environment variable and fetch it from there (e.g. os.getenv(SESSION_COOKIE) ).

Python">import requests

session_cookie = "your session cookie"  # or session_cookie = os.getenv(SESSION_COOKIE)

def get_puzzle_input(day, session_cookie, year=2024):

    url = f"https://adventofcode.com/{year}/day/{day}/input"
    cookies = {"session": session_cookie}
    response = requests.get(url, cookies=cookies)

    if response.status_code == 200:
        return response.text
    else:
        return None

puzzle_input = get_puzzle_input(1, session_cookie)

How to get the session cookie

Once you open up the input page, right click and select "inspect". Then switch to the "network" tab and press "command+R" (ctrl+R on windows). Switch to the "headers" tab and scroll down to cookies. You’ll see the session cookie there.

How to get the session cookie (image by author)
How to get the session cookie (image by author)

We now have the puzzle input. The input is given as shown below so the output of the get request is not two separate lists in a nice and clean format. We need to do some data manipulation.

First 6 rows of the puzzle 1 input (image by author)
First 6 rows of the puzzle 1 input (image by author)
puzzle_input = get_puzzle_input(1, session_cookie)

print(puzzle_input)
80784   47731
81682   36089
22289   41038
79525   17481
62156   70590
...

The puzzle input is a single string and there are spaces and new lines between items. We can split the string at newline characters ("n") to get a list of lines. Then, we can split each line at the space character. The first item belongs to the left list and the last item belongs to the right list.

To do this operation for all the items in the lists at the same time, we’ll use a list comprehension. It’s much more performant than a for loop that goes over each item in the list one by one.

lines = puzzle_input.split("n")[:-1] # exclude the last item since it's just a new line

left_list = [int(line.split(" ")[0]) for line in lines]
right_list = [int(line.split(" ")[-1]) for line in lines]

# print the first 5 items
print(left_list[:5])
[80784, 81682, 22289, 79525, 62156]

print(right_list[:5])
[47731, 36089, 41038, 17481, 70590]

The next operation is to sort both lists either in ascending or descending order. Then, we can find the difference between the first items, second items, and so on. Make sure to take the absolute value of the differences before adding them together. The final operation will be to sum these differences.

I’ll convert these lists to numpy arrays and then do the sorting, subtracting, and taking the sum.

# convert lists to numpy arrays and sort
left_arr = np.sort(np.array(left_list))
right_arr = np.sort(np.array(right_list))

# find the absolute value of element-wise differences and take the sum
sum_of_differences = np.abs(left_arr - right_arr).sum()

Day 1 – Part 2

In part 2, we’re asked to calculate the similarity score between the left and right list according to the following criteria:

  • Go through each item in the left list and find how many times it appears in the right list.
  • Then multiply the number by the number of occurrences to find the similarity scores per item.
  • Sum all the similarity scores to get the total similarity score.

The drawing below demonstrates these calculations:

(image by author)
(image by author)

We can solve the second part by using a list comprehension and the count method of Python lists, which returns the number of occurrences of an item.

# list of similarity scores
similarity_scores = [item * right_list.count(item) for item in left_list]

# total similarity score
sum(similarity_scores)

The item in the list comprehension is the item in the left list and the right_list.count(item) is the number of occurrences of this item in the right list. Multiplying these two gives us the similarity score for that item. Then, we take the sum of the similarity scores for all items.

Day 1 is complete. Stay tuned for Day 2 🙂


Related Articles

Some areas of this page may shift around if you resize the browser window. Be sure to check heading and document order.