Compare commits

...

3 commits

Author SHA1 Message Date
dece 2a7d50eb22 lint 2020-12-23 21:05:48 +01:00
dece adf770f70b Day 21 2020-12-23 21:05:38 +01:00
dece 8ff3b4faa0 Day 22 2020-12-23 03:11:17 +01:00
4 changed files with 100 additions and 4 deletions

View file

@ -1,7 +1,5 @@
import sys
from collections import defaultdict
from functools import reduce
from itertools import permutations
def main():

43
2020/day21.py Normal file
View file

@ -0,0 +1,43 @@
import re
import sys
from functools import reduce
LINE_RE = re.compile(r"(.+) \(contains (.+)\)")
def main():
lines = [line.rstrip() for line in sys.stdin]
foods = []
for line in lines:
i, a = LINE_RE.match(line).groups()
foods.append((set(i.split()), set(a.split(", "))))
ingredients = set(i for il, _ in foods for i in il)
allergens = set(a for _, al in foods for a in al)
# Part 1
matches = {}
while len(matches) < len(allergens):
for allergen in allergens:
p_ings = [
set(filter(lambda i: i not in matches, f[0]))
for f in foods if allergen in f[1]
]
c_ings = reduce(lambda a, b: a & b, p_ings, ingredients)
if len(c_ings) == 1:
i = c_ings.pop()
matches[i] = allergen
clean_ings = ingredients.difference(set(matches.keys()))
num_appearances = sum(
ci in fis
for fis, _ in foods
for ci in clean_ings
)
print(f"Clean ingredients appear {num_appearances} times.")
# Part 2
canonical = ",".join(
f for f, a in sorted(matches.items(), key=lambda m: m[1])
)
print("Canonical list:", canonical)
if __name__ == "__main__":
main()

57
2020/day22.py Normal file
View file

@ -0,0 +1,57 @@
import sys
def main():
lines = [line.rstrip() for line in sys.stdin]
deck1, deck2 = parse_lines(lines)
# Part 1
while deck1 and deck2:
c1, c2 = deck1.pop(0), deck2.pop(0)
if c1 > c2:
deck1 += [c1, c2]
else:
deck2 += [c2, c1]
deck_win = deck1 or deck2
print("Score:", score(deck_win))
# Part 2
deck1, deck2 = parse_lines(lines)
winner = rec_game(deck1, deck2)
deck_win = deck1 if winner == 1 else deck2
print("Score:", score(deck_win))
def parse_lines(lines):
deck1, deck2 = [], []
for line in lines:
if not line:
continue
if line.startswith("P"):
deck = deck1 if int(line[7:8]) == 1 else deck2
else:
deck.append(int(line))
return deck1, deck2
def score(deck):
return sum(c * (i + 1) for i, c in enumerate(reversed(deck)))
def rec_game(deck1, deck2):
past_decks = set()
while deck1 and deck2:
h = tuple(deck1), tuple(deck2)
if h in past_decks:
return 1
past_decks.add(h)
c1, c2 = deck1.pop(0), deck2.pop(0)
if len(deck1) >= c1 and len(deck2) >= c2:
if rec_game(deck1[:c1], deck2[:c2]) == 1:
deck1 += [c1, c2]
else:
deck2 += [c2, c1]
elif c1 > c2:
deck1 += [c1, c2]
else:
deck2 += [c2, c1]
return 1 if deck1 else 2
if __name__ == "__main__":
main()

View file

@ -6,11 +6,9 @@ from datetime import date
TEMPLATE = """\
import sys
def main():
lines = [line.rstrip() for line in sys.stdin]
if __name__ == "__main__":
main()
"""