From 68bc22ce3139786fc6b39dab95dbe83d5cc486ef Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Tue, 21 Dec 2021 11:52:37 +0000 Subject: day 21 --- 21.py | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 21.py diff --git a/21.py b/21.py new file mode 100644 index 0000000..674d95e --- /dev/null +++ b/21.py @@ -0,0 +1,39 @@ +from itertools import count +from re import compile as re_compile +from utils import open_day +from functools import cache, reduce + +pattern = re_compile(r'Player \d+ starting position: (\d+)') +with open_day(21) as f: + positions = tuple(int(pattern.match(line).group(1)) - 1 for line in f) + +def part1(positions): + poss = list(positions) + scores = [0 for _ in poss] + for roll in count(): + rolled = (3 * roll + 1) * 3 + 3 + player = roll % len(poss) + poss[player] += rolled + poss[player] %= 10 + scores[player] += poss[player] + 1 + if scores[player] >= 1000: + return [score * (roll + 1) * 3 for score in scores if score < 1000][0] + +@cache +def part2(positions, scores=(0, 0), player=0, maxscore=21): + dirac_triples = ((1, 3), (3, 4), (6, 5), (7, 6), (6, 7), (3, 8), (1, 9)) + def times(t, c): return (t[0] * c, t[1] * c) + def tupsum(a, b): return (a[0] + b[0], a[1] + b[1]) + def turn(rolled): + nposs = list(positions) + nscores = list(scores) + nposs[player] += rolled + nposs[player] %= 10 + nscores[player] += nposs[player] + 1 + if nscores[player] >= maxscore: + return (player == 0, player != 0) + return part2(tuple(nposs), tuple(nscores), int(not player), maxscore) + return reduce(tupsum, (times(turn(roll), count) for count, roll in dirac_triples)) + +print(part1(positions)) +print(max(part2(positions))) -- cgit v1.2.3-54-g00ecf