Solution to problem 13 in Python
This commit is contained in:
parent
1d0137c0e8
commit
a38def1920
123
src/Year_2015/P13.py
Normal file
123
src/Year_2015/P13.py
Normal file
@ -0,0 +1,123 @@
|
||||
# --- Day 13: Knights of the Dinner Table ---
|
||||
|
||||
# In years past, the holiday feast with your family hasn't gone so well. Not
|
||||
# everyone gets along! This year, you resolve, will be different. You're going
|
||||
# to find the optimal seating arrangement and avoid all those awkward
|
||||
# conversations.
|
||||
|
||||
# You start by writing up a list of everyone invited and the amount their
|
||||
# happiness would increase or decrease if they were to find themselves sitting
|
||||
# next to each other person. You have a circular table that will be just big
|
||||
# enough to fit everyone comfortably, and so each person will have exactly two
|
||||
# neighbors.
|
||||
|
||||
# For example, suppose you have only four attendees planned, and you calculate
|
||||
# their potential happiness as follows:
|
||||
|
||||
# Alice would gain 54 happiness units by sitting next to Bob.
|
||||
# Alice would lose 79 happiness units by sitting next to Carol.
|
||||
# Alice would lose 2 happiness units by sitting next to David.
|
||||
# Bob would gain 83 happiness units by sitting next to Alice.
|
||||
# Bob would lose 7 happiness units by sitting next to Carol.
|
||||
# Bob would lose 63 happiness units by sitting next to David.
|
||||
# Carol would lose 62 happiness units by sitting next to Alice.
|
||||
# Carol would gain 60 happiness units by sitting next to Bob.
|
||||
# Carol would gain 55 happiness units by sitting next to David.
|
||||
# David would gain 46 happiness units by sitting next to Alice.
|
||||
# David would lose 7 happiness units by sitting next to Bob.
|
||||
# David would gain 41 happiness units by sitting next to Carol.
|
||||
|
||||
# Then, if you seat Alice next to David, Alice would lose 2 happiness units
|
||||
# (because David talks so much), but David would gain 46 happiness units
|
||||
# (because Alice is such a good listener), for a total change of 44.
|
||||
|
||||
# If you continue around the table, you could then seat Bob next to Alice (Bob
|
||||
# gains 83, Alice gains 54). Finally, seat Carol, who sits next to Bob (Carol
|
||||
# gains 60, Bob loses 7) and David (Carol gains 55, David gains 41). The
|
||||
# arrangement looks like this:
|
||||
|
||||
# +41 +46
|
||||
# +55 David -2
|
||||
# Carol Alice
|
||||
# +60 Bob +54
|
||||
# -7 +83
|
||||
|
||||
# After trying every other seating arrangement in this hypothetical scenario,
|
||||
# you find that this one is the most optimal, with a total change in happiness
|
||||
# of 330.
|
||||
|
||||
# What is the total change in happiness for the optimal seating arrangement of
|
||||
# the actual guest list?
|
||||
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from itertools import permutations
|
||||
from typing import DefaultDict
|
||||
|
||||
with open("files/P13.txt") as f:
|
||||
sittings = [line for line in f.read().strip().split("\n")]
|
||||
|
||||
|
||||
arrengements: DefaultDict = defaultdict(dict)
|
||||
for happiness in sittings:
|
||||
pattern = r"(?P<p1>\S+) would (?P<op>lose|gain) (?P<val>\d+) happiness units by sitting next to (?P<p2>\S+)."
|
||||
matches = re.match(pattern, happiness)
|
||||
p1, op, val, p2 = re.match(pattern, happiness).group(
|
||||
"p1", "op", "val", "p2"
|
||||
)
|
||||
arrengements[p1][p2] = -int(val) if op == "lose" else int(val)
|
||||
|
||||
|
||||
def part_1() -> None:
|
||||
max_happiness = 0
|
||||
for ordering in permutations(arrengements.keys()):
|
||||
happiness = sum(
|
||||
arrengements[a][b] + arrengements[b][a]
|
||||
for a, b in zip(ordering, ordering[1:])
|
||||
)
|
||||
happiness += (
|
||||
arrengements[ordering[0]][ordering[-1]]
|
||||
+ arrengements[ordering[-1]][ordering[0]]
|
||||
)
|
||||
max_happiness = max(max_happiness, happiness)
|
||||
print(f"The total change in happiness is {max_happiness}")
|
||||
|
||||
|
||||
# --- Part Two ---
|
||||
|
||||
# In all the commotion, you realize that you forgot to seat yourself. At this
|
||||
# point, you're pretty apathetic toward the whole thing, and your happiness
|
||||
# wouldn't really go up or down regardless of who you sit next to. You assume
|
||||
# everyone else would be just as ambivalent about sitting next to you, too.
|
||||
|
||||
# So, add yourself to the list, and give all happiness relationships that
|
||||
# involve you a score of 0.
|
||||
|
||||
# What is the total change in happiness for the optimal seating arrangement
|
||||
# that actually includes yourself?
|
||||
|
||||
|
||||
def part_2() -> None:
|
||||
for somebody in list(arrengements.keys()):
|
||||
arrengements["me"][somebody] = 0
|
||||
arrengements[somebody]["me"] = 0
|
||||
|
||||
max_happiness = 0
|
||||
for ordering in permutations(arrengements.keys()):
|
||||
happiness = sum(
|
||||
arrengements[a][b] + arrengements[b][a]
|
||||
for a, b in zip(ordering, ordering[1:])
|
||||
)
|
||||
happiness += (
|
||||
arrengements[ordering[0]][ordering[-1]]
|
||||
+ arrengements[ordering[-1]][ordering[0]]
|
||||
)
|
||||
max_happiness = max(max_happiness, happiness)
|
||||
print(
|
||||
f"The total change in happiness is {max_happiness}, including myself"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
part_1()
|
||||
part_2()
|
Loading…
Reference in New Issue
Block a user