2020: day22: optimize part 2

Use the score of the two decks in the set, instead of copying and
storing copies of both decks.
This commit is contained in:
Antoine Martin 2020-12-22 14:58:28 +01:00
parent 17bf26ea14
commit 2ddd6b2bfc

View file

@ -41,17 +41,20 @@ fn play_game(mut deck_a: Deck, mut deck_b: Deck) -> Deck {
} }
fn play_recursive_game(mut deck_a: Deck, mut deck_b: Deck) -> (Deck, bool) { fn play_recursive_game(mut deck_a: Deck, mut deck_b: Deck) -> (Deck, bool) {
let mut seen: HashSet<(Deck, Deck)> = HashSet::new(); let mut seen: HashSet<u64> = HashSet::new();
while !(deck_a.0.is_empty() || deck_b.0.is_empty()) { while !(deck_a.0.is_empty() || deck_b.0.is_empty()) {
// Before either player deals a card, if there was a previous round in this game that had // Before either player deals a card, if there was a previous round in this game that had
// exactly the same cards in the same order in the same players' decks, the game instantly // exactly the same cards in the same order in the same players' decks, the game instantly
// ends in a win for player 1. Previous rounds from other games are not considered. (This // ends in a win for player 1. Previous rounds from other games are not considered. (This
// prevents infinite games of Recursive Combat, which everyone agrees is a bad idea.) // prevents infinite games of Recursive Combat, which everyone agrees is a bad idea.)
if seen.contains(&(deck_a.clone(), deck_b.clone())) { let score_a = deck_score(&deck_a);
let score_b = deck_score(&deck_b);
let hash = score_a * 100_000 + score_b;
if seen.contains(&hash) {
return (deck_a, true); return (deck_a, true);
} else { } else {
seen.insert((deck_a.clone(), deck_b.clone())); seen.insert(hash);
} }
// Otherwise, this round's cards must be in a new configuration; the players begin the round // Otherwise, this round's cards must be in a new configuration; the players begin the round