Solution to problem 2 in Python
This commit is contained in:
parent
c78882e46f
commit
c0c65bb040
119
src/Year_2018/P2.py
Normal file
119
src/Year_2018/P2.py
Normal file
@ -0,0 +1,119 @@
|
||||
# --- Day 2: Inventory Management System ---
|
||||
|
||||
# You stop falling through time, catch your breath, and check the screen on the
|
||||
# device. "Destination reached. Current Year: 1518. Current Location: North
|
||||
# Pole Utility Closet 83N10." You made it! Now, to find those anomalies.
|
||||
|
||||
# Outside the utility closet, you hear footsteps and a voice. "...I'm not sure
|
||||
# either. But now that so many people have chimneys, maybe he could sneak in
|
||||
# that way?" Another voice responds, "Actually, we've been working on a new
|
||||
# kind of suit that would let him fit through tight spaces like that. But, I
|
||||
# heard that a few days ago, they lost the prototype fabric, the design plans,
|
||||
# everything! Nobody on the team can even seem to remember important details of
|
||||
# the project!"
|
||||
|
||||
# "Wouldn't they have had enough fabric to fill several boxes in the warehouse?
|
||||
# They'd be stored together, so the box IDs should be similar. Too bad it would
|
||||
# take forever to search the warehouse for two similar box IDs..." They walk
|
||||
# too far away to hear any more.
|
||||
|
||||
# Late at night, you sneak to the warehouse - who knows what kinds of paradoxes
|
||||
# you could cause if you were discovered - and use your fancy wrist device to
|
||||
# quickly scan every box and produce a list of the likely candidates (your
|
||||
# puzzle input).
|
||||
|
||||
# To make sure you didn't miss any, you scan the likely candidate boxes again,
|
||||
# counting the number that have an ID containing exactly two of any letter and
|
||||
# then separately counting those with exactly three of any letter. You can
|
||||
# multiply those two counts together to get a rudimentary checksum and compare
|
||||
# it to what your device predicts.
|
||||
|
||||
# For example, if you see the following box IDs:
|
||||
|
||||
# abcdef contains no letters that appear exactly two or three times.
|
||||
# bababc contains two a and three b, so it counts for both.
|
||||
# abbcde contains two b, but no letter appears exactly three times.
|
||||
# abcccd contains three c, but no letter appears exactly two times.
|
||||
# aabcdd contains two a and two d, but it only counts once.
|
||||
# abcdee contains two e.
|
||||
# ababab contains three a and three b, but it only counts once.
|
||||
|
||||
# Of these box IDs, four of them contain a letter which appears exactly twice,
|
||||
# and three of them contain a letter which appears exactly three times.
|
||||
# Multiplying these together produces a checksum of 4 * 3 = 12.
|
||||
|
||||
# What is the checksum for your list of box IDs?
|
||||
|
||||
from itertools import combinations
|
||||
from typing import Dict
|
||||
|
||||
with open("files/P2.txt") as f:
|
||||
IDs = [line for line in f.read().strip().split()]
|
||||
|
||||
|
||||
def part_1() -> None:
|
||||
twice, three_times = 0, 0
|
||||
for word in IDs:
|
||||
twice_added, three_times_added = False, False
|
||||
while not twice_added and not three_times_added:
|
||||
for letter in word:
|
||||
counts = word.count(letter)
|
||||
if counts == 2 and not twice_added:
|
||||
twice += 1
|
||||
twice_added = True
|
||||
elif counts == 3 and not three_times_added:
|
||||
three_times += 1
|
||||
three_times_added = True
|
||||
|
||||
print(f"The checksum for my list is {twice*three_times}")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# Confident that your list of box IDs is complete, you're ready to find the
|
||||
# boxes full of prototype fabric.
|
||||
|
||||
# The boxes will have IDs which differ by exactly one character at the same
|
||||
# position in both strings. For example, given the following box IDs:
|
||||
|
||||
# abcde
|
||||
# fghij
|
||||
# klmno
|
||||
# pqrst
|
||||
# fguij
|
||||
# axcye
|
||||
# wvxyz
|
||||
|
||||
# The IDs abcde and axcye are close, but they differ by two characters (the
|
||||
# second and fourth). However, the IDs fghij and fguij differ by exactly one
|
||||
# character, the third (h and u). Those must be the correct boxes.
|
||||
|
||||
# What letters are common between the two correct box IDs? (In the example
|
||||
# above, this is found by removing the differing character from either ID,
|
||||
# producing fgij.)
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
# each entry has word as key and a dict of all letters as value
|
||||
dict_IDs: Dict[str, Dict[int, str]] = {}
|
||||
for word in IDs:
|
||||
dict_IDs[word] = {}
|
||||
for pos, letter in enumerate(word):
|
||||
dict_IDs[word][pos] = letter
|
||||
|
||||
# create combinations of two values for later comparison
|
||||
pairs = list(combinations(dict_IDs.values(), 2))
|
||||
|
||||
for d1, d2 in pairs:
|
||||
set1 = set(d1.items())
|
||||
set2 = set(d2.items())
|
||||
# only one letter on each set is different
|
||||
if len(set1 ^ set2) == 2:
|
||||
# remove extra letter from first set
|
||||
d1.pop(list(set1 ^ set2)[1][0])
|
||||
print(f"Common letters are {''.join(d1.values())}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
Loading…
Reference in New Issue
Block a user