Challenge – Part 1
https://adventofcode.com/2022/day/3
Problem
vJrwpWtwJgWrhcsFMMfFFhFp jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL PmmdzqPrVvPwwTWBwg wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn ttgJtRGJQctTZtZT CrZsJsPPZsGzwwsLwLmpwMDw
The first rucksack contains the items vJrwpWtwJgWrhcsFMMfFFhFp, which means its first compartment contains the items vJrwpWtwJgWr, while the second compartment contains the items hcsFMMfFFhFp. The only item type that appears in both compartments is lowercase p.
The second rucksack’s compartments contain jqHRNqRjqzjGDLGL and rsFMfFZSrLrFZsSL. The only item type that appears in both compartments is uppercase L.
The third rucksack’s compartments contain PmmdzqPrV and vPwwTWBwg; the only common item type is uppercase P.
The fourth rucksack’s compartments only share item type v.
The fifth rucksack’s compartments only share item type t.
The sixth rucksack’s compartments only share item type s.
To help prioritize item rearrangement, every item type can be converted to a priority:
Lowercase item types a through z have priorities 1 through 26.
Uppercase item types A through Z have priorities 27 through 52.
In the above example, the priority of the item type that appears in both compartments of each rucksack is 16 (p), 38 (L), 42 (P), 22 (v), 20 (t), and 19 (s); the sum of these is 157.
Find the item type that appears in both compartments of each rucksack. What is the sum of the priorities of those item types?
Solution
We put the sample data into a multi-line string:
data="""vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw"""
We check if we can get the first rucksack:
def test_split_rucksacks():
first_rucksack = data.split("\n")[0]
assert first_rucksack == "vJrwpWtwJgWrhcsFMMfFFhFp"
Due to different length of each rucksack we need to determine the splitting point:
def test_split_rucksack_items():
first_rucksack = data.split("\n")[0]
split_point = len(first_rucksack)//2
first_rucksack_item = first_rucksack[0:split_point]
assert first_rucksack_item == "vJrwpWtwJgWr"
second_rucksack_item = first_rucksack[split_point:]
assert second_rucksack_item == "hcsFMMfFFhFp"
A neat solution for checking common characters is putting the strings into sets and logically and them
def test_check_common_char():
first_rucksack_item = "vJrwpWtwJgWr"
second_rucksack_item = "hcsFMMfFFhFp"
a = list(set(first_rucksack_item) & set(second_rucksack_item))
assert a == ['p']
To get the corresponding value for the characters we use the built-in ascii_letters:
def test_lookup_char_value():
chars = string.ascii_letters
value = chars.index('p') + 1
assert value == 16
value = chars.index('L') + 1
assert value == 38
Putting it all together:
def test_sum_priorities_data():
with open("aoc_data_03.txt", "r") as f:
data_from_file = f.read()
sum_of_list = 0
chars = string.ascii_letters
rucksacks = data_from_file.split("\n")
for rucksack in rucksacks:
split_point = len(rucksack) // 2
first_rucksack_item = rucksack[0:split_point]
second_rucksack_item = rucksack[split_point:]
common_char = list(set(first_rucksack_item) & set(second_rucksack_item))
value = chars.index(common_char[0]) + 1
sum_of_list += value
assert sum_of_list == 8202