diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2020-12-22 11:20:26 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2020-12-22 11:20:26 +0100 |
| commit | 167ad132e3c70fab367439c095bd6cc18f8d4a62 (patch) | |
| tree | 206be4e60e6d87882ec0cec5b589d7d74e90850e | |
| parent | 0a90b3cead9b4e0a19c962f79a9170fc2781f791 (diff) | |
| download | aoc-167ad132e3c70fab367439c095bd6cc18f8d4a62.tar.gz | |
d22
| -rw-r--r-- | 20/py/d22.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/20/py/d22.py b/20/py/d22.py new file mode 100644 index 0000000..e32d01a --- /dev/null +++ b/20/py/d22.py @@ -0,0 +1,65 @@ +import aoc20 +import sys +from collections import deque +import functools +import itertools + + +def pt1(_in): + _in = "".join(_in) + player1 = deque([int(n) for n in _in.split("\n\n")[0].split("\n")[1:]]) + player2 = deque([int(n) for n in _in.split("\n\n")[1].split("\n")[1:-1]]) + + while all((player1, player2)): + c1, c2 = player1.popleft(), player2.popleft() + if c1 > c2: + player1.append(c1) + player1.append(c2) + else: + player2.append(c2) + player2.append(c1) + + return sum((i+1) * v + for i, v in enumerate(reversed(player1 if player1 else player2))) + + +mem = dict() +def play(player1, player2): + call_state = tuple((tuple(player1), tuple(player2))) + if call_state in mem: + return mem[call_state] + seen = set() + while all((player1, player2)): + state = tuple((tuple(player1), tuple(player2))) + if state in seen: + mem[call_state] = 1 + return 1 + seen.add(state) + c1, c2 = player1.popleft(), player2.popleft() + if all(len(p) >= c for c, p in zip((c1,c2), (player1, player2))): + win = play(deque(itertools.islice(player1, 0, c1)), deque(itertools.islice(player2, 0, c2))) + else: + win = 1 if c1 > c2 else 2 + if win == 1: + player1.append(c1) + player1.append(c2) + else: + player2.append(c2) + player2.append(c1) + mem[call_state] = 1 if player1 else 2 + return 1 if player1 else 2 + + + +def pt2(_in): + _in = "".join(_in) + player1 = deque([int(n) for n in _in.split("\n\n")[0].split("\n")[1:]]) + player2 = deque([int(n) for n in _in.split("\n\n")[1].split("\n")[1:-1]]) + play(player1, player2) + return sum((i+1) * v + for i, v in enumerate(reversed(player1 if player1 else player2))) + +if __name__ == "__main__": + _in = aoc20.read_input(sys.argv[1:], 22) + print(pt1(_in)) + print(pt2(_in)) |
