This commit is contained in:
Glenn Griffin 2020-12-21 22:02:16 -08:00
parent 3f8af0c1e8
commit f004fa549f
3 changed files with 141 additions and 0 deletions

53
input/2020/day22.txt Normal file
View File

@ -0,0 +1,53 @@
Player 1:
10
21
37
2
47
13
6
29
9
3
4
48
46
25
44
41
23
20
24
12
45
43
5
27
50
Player 2:
39
42
31
36
7
1
49
19
40
35
8
11
18
30
14
17
15
34
26
33
32
38
28
16
22

87
src/day22.rs Normal file
View File

@ -0,0 +1,87 @@
use crate::split_once;
use aoc_runner_derive::aoc;
use std::borrow::Cow;
use std::collections::{HashSet, VecDeque};
fn deck_score(deck: VecDeque<usize>) -> usize {
deck.iter()
.rev()
.enumerate()
.map(|(idx, value)| (idx + 1) * value)
.sum()
}
#[aoc(day22, part1)]
fn solve_d22_p1(input: &str) -> usize {
let (p1, p2) = split_once(input, "\n\n").unwrap();
let mut p1_deck: VecDeque<usize> = p1.split('\n').skip(1).map(|x| x.parse().unwrap()).collect();
let mut p2_deck: VecDeque<usize> = p2.split('\n').skip(1).map(|x| x.parse().unwrap()).collect();
while !p1_deck.is_empty() && !p2_deck.is_empty() {
let p1_value = p1_deck.pop_front().unwrap();
let p2_value = p2_deck.pop_front().unwrap();
if p1_value > p2_value {
p1_deck.push_back(p1_value);
p1_deck.push_back(p2_value);
} else {
p2_deck.push_back(p2_value);
p2_deck.push_back(p1_value);
}
}
deck_score(if p1_deck.is_empty() { p2_deck } else { p1_deck })
}
enum Winner {
Player1(VecDeque<usize>),
Player2(VecDeque<usize>),
}
#[aoc(day22, part2)]
fn solve_d22_p2(input: &str) -> usize {
let (p1, p2) = split_once(input, "\n\n").unwrap();
let p1_deck: VecDeque<usize> = p1.split('\n').skip(1).map(|x| x.parse().unwrap()).collect();
let p2_deck: VecDeque<usize> = p2.split('\n').skip(1).map(|x| x.parse().unwrap()).collect();
match play_recursive_combat(p1_deck, p2_deck) {
Winner::Player1(deck) | Winner::Player2(deck) => deck_score(deck),
}
}
fn play_recursive_combat(mut p1_deck: VecDeque<usize>, mut p2_deck: VecDeque<usize>) -> Winner {
let mut previous_rounds = HashSet::new();
while !p1_deck.is_empty() && !p2_deck.is_empty() {
if previous_rounds.contains(&(Cow::Borrowed(&p1_deck), Cow::Borrowed(&p2_deck))) {
return Winner::Player1(p1_deck);
}
previous_rounds.insert((Cow::Owned(p1_deck.clone()), Cow::Owned(p2_deck.clone())));
let p1_value = p1_deck.pop_front().unwrap();
let p2_value = p2_deck.pop_front().unwrap();
if p1_deck.len() >= p1_value && p2_deck.len() >= p2_value {
match play_recursive_combat(
p1_deck.iter().copied().take(p1_value).collect(),
p2_deck.iter().copied().take(p2_value).collect(),
) {
Winner::Player1(_) => {
p1_deck.push_back(p1_value);
p1_deck.push_back(p2_value);
}
Winner::Player2(_) => {
p2_deck.push_back(p2_value);
p2_deck.push_back(p1_value);
}
}
} else {
if p1_value > p2_value {
p1_deck.push_back(p1_value);
p1_deck.push_back(p2_value);
} else {
p2_deck.push_back(p2_value);
p2_deck.push_back(p1_value);
}
}
}
if p1_deck.is_empty() {
Winner::Player2(p2_deck)
} else {
Winner::Player1(p1_deck)
}
}

View File

@ -12,6 +12,7 @@ pub mod day19;
pub mod day2; pub mod day2;
pub mod day20; pub mod day20;
pub mod day21; pub mod day21;
pub mod day22;
pub mod day3; pub mod day3;
pub mod day4; pub mod day4;
pub mod day5; pub mod day5;