How to solve Advent of Code 2022 - Day 3 with Python
If you missed any previous days, click here for all my content about that: Advent of Code, if you want to know why you should participate and try to code the solution for yourself, click here: Advent Of Code 2022 – 7 Reasons why you should participate. If you're here to see the solution of Day 3, continue reading ;)
GitHub Repository
https://github.com/GalaxyInfernoCodes/Advent_Of_Code_2022
I will upload all of my solutions there - in the form of Python (or Scala alternatives) notebooks. You have to use your own input for the "input.txt" since everyone gets their own and everyone needs to provide a different solution based on their input.
Day 3 Puzzle
On day 3 of Advent of Code, we had to organize rucksacks with each line being the contents of each rucksack:
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
As always, I read in all lines:
with open('input.txt', 'r') as f:
lines = f.readlines()
rucksacks = [entry.strip() for entry in lines]
Part 1
Then iterate over the rucksacks. Each is split in half to get the two compartments. To find the one common item, I used the set-intersection logic, which gives us exactly the common items needed.
To compute the item's score, I used the ASCII value of the character, because conveniently these count up from A to Z. I subtracted the base (ASCII from 'A'), so 'A' would then be 0, then I added the value of 27, because that is what 'A' should be according to the puzzle. Similar for 'a'.
rucksack_sum = 0
for rucksack in rucksacks:
# split in half
first_half = set(rucksack[:len(rucksack)//2])
second_half = set(rucksack[len(rucksack)//2:])
# get overlap through set logic (intersection of two sets)
overlap_char = (first_half.intersection(second_half)).pop()
# translate to ascii and substract the base ('A' is 65, 'B' is 66 and so on) and add the new base
if overlap_char.isupper():
rucksack_sum += ord(overlap_char) - ord('A') + 27
else:
rucksack_sum += ord(overlap_char) - ord('a') + 1
rucksack_sum
Part 2
Here we were supposed to check 3 rucksacks at once and again, find the intersection of these. For that I adapted the code slightly and extracted the first 3 rucksacks from the list using .pop()
in each iteration.
rucksack_sum = 0
while len(rucksacks) > 0:
# take out first 3 entries
first_rucksack = set(rucksacks.pop())
second_rucksack = set(rucksacks.pop())
third_rucksack = set(rucksacks.pop())
# get overlap through set logic (intersection of two sets applied twice)
overlap_char = ((first_rucksack.intersection(second_rucksack)).intersection(third_rucksack)).pop()
# translate to ascii and substract the base ('A' is 65, 'B' is 66 and so on) and add the new base
if overlap_char.isupper():
rucksack_sum += ord(overlap_char) - ord('A') + 27
else:
rucksack_sum += ord(overlap_char) - ord('a') + 1
rucksack_sum
Conclusion
I definitely preferred this one over yesterday's puzzle about Rock, Paper, Scissors :D Using intersection on sets always pleases the mathematician in me. However, the ASCII conversion felt a bit hack-y to me, but a fun flashback to coding C assignments and learning about the integer representation of all characters.