Advent of Code 2024 - Day 01 of 25
Table of Contents
The Advent of Code is a programming challenge that takes place between December 1st and 25th each year. The 2024 edition is the tenth event that is programming language independent - you can use any tools you want.
Every day, starting from December first, a new problem is released. Although the name is Advent of Code (Advent is a Christian event that precedes Christmas), the problems don’t necessarily involve religion, but are fun problems with Santa’s elves.
I learned about this tradition in Belgium, where children received calendars with a chocolate for each day of December until Christmas. And the little ones would look at the huge tablet with various chocolates, but could only eat one per day :-D. Here’s a photo to give you an idea:

Photo by Nick Fewings on Unsplash
The problems have various difficulty levels, which I’ll classify into three levels:
Easy Level: requires only Basic Python to solve. Programming logic, sets, lists, dictionaries, sorting, etc. If you’ve read all the chapters of my book, you should be able to solve easy level problems.
Medium Level: requires more knowledge about data structures, search algorithms, and even graphs.
Hard Level: this is where more complex problems start appearing, which can be solved with dynamic programming, backtracking, etc. They usually appear around day 9 or 10. These problems require heuristics or a good choice of algorithms to be completed in a reasonable time (less than 10 minutes). They encourage the search for more efficient solutions.
The problems have well-structured parts, usually starting with a small story to put the victim in the event’s spirit :-D. Soon after, a test vector is described. The test vector is an input example where the problem is demonstrated in the format: input and output. In other words, such data goes in and such results should come out. This part is very important, as it’s how you’ll start solving the problem.
What I usually do is write a small program that uses the same test vector (as input) and start writing a program to generate the result (output). When my program starts passing the tests, I switch the test vector for the actual problem input. You have to get the input from the website, and I believe it changes from user to user, to prevent answers from being shared quickly and keep the competition fair. One part of Advent of Code that I don’t recommend is the programming competition. Competitors wait for the program to come out in the middle of the night to be the first to solve and publish the answer. The earlier you post the correct answer, the more points you get, but I warn you it’s tough - the “pros” solve these problems in less than 10 minutes.
Once you have the results for the problem input, you can post it on the site. When submitting your answer, the site indicates whether it’s correct or not, sometimes giving hints like “number too large” or “too small”. You can submit as many answers as you want until you get it right, but you have to wait a minute if you’re wrong. The idea is that you understand the problem, fix the issue, and calculate a new answer.
After submitting the first correct answer, the site will present a second part of the problem. The second part usually modifies the first. The elves typically discover they did something wrong and change the calculation of your algorithm. This change is sometimes quite simple but may require a new solution to be developed.
For each correct part, you earn a star, two per day. Each completed day unlocks a Christmas tree drawing.
Tips#
If it’s your first time participating, I recommend teaming up with friends and colleagues to solve the problems together. There are internet forums for this purpose, like the Advent of Code Subreddit. But try to solve it alone first, and if you need to look at the answer, try to understand what needs to be done.
Don’t worry if you fall behind a day or two; the important thing is to come back and continue. I always forget after a few days; this year, I’ll try to do it until the end, posting my solutions the next day or later. If things get tough, use my book’s Telegram group to ask for help (address in the book :-D). Don’t forget that some problems are really difficult and have some tricks; don’t get discouraged if you can’t solve them, look for the solution and see which algorithms were applied.
Organize the code into functions, as it’s very common to reuse routines, especially for reading the input file or transforming input into lists or dictionaries. You’ll end up creating routines to display data and help with screen debugging (some problems generate text-mode graphics…). It’s a good opportunity to learn about Python’s rich library.
Answer for Day 12/01/24#
from aux.files import read_file_without_blank_lines
EXAMPLE_INPUT = """
3 4
4 3
2 5
1 3
3 9
3 3
"""
PROBLEM_INPUT = read_file_without_blank_lines("01/input.txt")
def generate_lists(inputs):
left_list = []
right_list = []
for input_line in inputs.splitlines():
left, right = input_line.split()
left_list.append(int(left))
right_list.append(int(right))
return left_list, right_list
def calculate_distance(left_list, right_list):
return [
abs(left - right) for left, right in zip(sorted(left_list), sorted(right_list))
]
def count_occurrences(list_: list[int]) -> dict[int, int]:
occurrences: dict[int, int] = {}
for element in list_:
if element not in occurrences:
occurrences[element] = list_.count(element)
return occurrences
def similarity_score(left_list, right_list):
occurrences = count_occurrences(right_list)
return sum([element * occurrences.get(element, 0) for element in left_list])
# Problem test
left, right = generate_lists(EXAMPLE_INPUT)
example_distance = sum(calculate_distance(left, right))
assert example_distance == 11
print("Example distance:", example_distance)
# Problem answer
left, right = generate_lists(PROBLEM_INPUT)
problem_distance = sum(calculate_distance(left, right))
print("Problem distance:", problem_distance)
# Part 2
# Problem test
left, right = generate_lists(EXAMPLE_INPUT)
example_score = similarity_score(left, right)
print("Example score:", example_score)
assert example_score == 31
# Problem answer
left, right = generate_lists(PROBLEM_INPUT)
problem_score = similarity_score(left, right)
print("Problem score:", problem_score)
# Output:
# Example distance: 11
# Problem distance: 936063
# Example score: 31
# Problem score: 23150395
Module: aux.files
def read_file(file_name: str) -> str:
with open(file_name, "r") as f:
return f.read()
def read_file_without_blank_lines(file_name: str) -> str:
return "\n".join(
zz
for line in read_file(file_name).splitlines()
if len(zz := line.strip()) > 0
)
def list_per_line(file_name: str) -> list[str]:
return [
[int(l) for l in line.split()]
for line in read_file_without_blank_lines(file_name).splitlines()
]
In my case, I create a directory for each day and put both the program and input files in the same place. To perform the tests, I’m using Python’s assert command. It simply causes an exception in the program if it returns false. Assert is excellent, especially when you start modifying the program, to make sure you haven’t created a bug while trying to solve another.
And that’s the answer for day one. I’ve already solved today’s (12/02/24), and if I have time (tomorrow is my birthday :-D), I’ll post it tomorrow or Wednesday.