Update day22.py

This commit is contained in:
kamoshi 2020-12-22 20:33:18 +01:00 committed by GitHub
parent bbcc9e1bb3
commit df3cd1967a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -19,81 +19,42 @@ def parse_data() -> Tuple[list[int], list[int]]:
return data
def solve_p1(player1: list[int], player2: list[int]) -> int:
stack1 = list(reversed(player1))
stack2 = list(reversed(player2))
def play_game(player1: list[int], player2: list[int], rec: bool = False) -> Tuple[int, list[int]]:
past_rounds: set[str] = set()
hand1, hand2 = player1[:], player2[:]
while len(stack1) > 0 and len(stack2) > 0:
number1 = stack1.pop()
number2 = stack2.pop()
if number1 > number2:
stack1.insert(0, number1)
stack1.insert(0, number2)
def snapshot() -> str:
return f"{hand1}{hand2}"
while len(hand1) > 0 and len(hand2) > 0:
if (curr_snapshot := snapshot()) in past_rounds:
return 1, hand1
past_rounds.add(curr_snapshot)
card1, card2 = hand1.pop(0), hand2.pop(0)
if rec and len(hand1) >= card1 and len(hand2) >= card2:
winner, _ = play_game(hand1[:card1], hand2[:card2], rec=True)
else:
stack2.insert(0, number2)
stack2.insert(0, number1)
winner = 1 if card1 > card2 else 2
winning = stack1 if len(stack1) > 0 else stack2
return sum(x*y for (x, y) in (zip(winning, [x for x in range(1, len(winning)+1)])))
if winner == 1:
hand1.append(card1)
hand1.append(card2)
else:
hand2.append(card2)
hand2.append(card1)
if len(hand2) == 0:
return 1, hand1
else:
return 2, hand2
def score(hand: list[int]) -> int:
return sum(x*y for (x, y) in zip(reversed(hand), [x for x in range(1, len(hand)+1)]))
PLAYER1, PLAYER2 = parse_data()
print(solve_p1(PLAYER1, PLAYER2))
def play_game(cache: dict[str, int], player1: list[int], player2: list[int]) -> (int, list[int]):
previous_rounds: set[str] = set()
stack1, stack2 = list(reversed(player1)), list(reversed(player2))
def round_snapshot() -> str:
return f"{stack1}|{stack2}"
def normal_round() -> None:
_number1, _number2 = stack1.pop(), stack2.pop()
if _number1 > _number2:
stack1.insert(0, _number1)
stack1.insert(0, _number2)
else:
stack2.insert(0, _number2)
stack2.insert(0, _number1)
while len(stack1) > 0 and len(stack2) > 0:
if (snapshot := round_snapshot()) in previous_rounds:
return 1, stack1
else:
previous_rounds.add(snapshot)
if len(stack1) > stack1[len(stack1)-1] and len(stack2) > stack2[len(stack2)-1]:
number1, number2 = stack1.pop(), stack2.pop()
sub_deck1, sub_deck2 = stack1[1-number1:], stack2[1-number2:]
# Check cache for winner
if (sub_snapshot := f"{sub_deck1}|{sub_deck2}") not in cache:
winner, _ = play_game(cache, sub_deck1, sub_deck2)
cache[sub_snapshot] = winner
else:
winner = cache[sub_snapshot]
if winner == 1:
stack1.insert(0, number1)
stack1.insert(0, number2)
else:
stack2.insert(0, number2)
stack2.insert(0, number1)
else:
normal_round()
if len(stack1) > 0:
return 1, stack1
else:
return 2, stack2
# PART 2 is Broken for now
def solve_p2(player1: list[int], player2: list[int]) -> int:
cache: dict[str, int] = {}
winner, winning = play_game(cache, player1, player2)
return sum(x*y for (x, y) in (zip(winning, [x for x in range(1, len(winning)+1)])))
print(solve_p2(PLAYER1, PLAYER2))
print(score(play_game(PLAYER1, PLAYER2, rec=False)[1]))
print(score(play_game(PLAYER1, PLAYER2, rec=True)[1]))