[TASK] Solved day 22 part 1 (part 2 partly solved)

This commit is contained in:
2020-12-22 10:54:06 +01:00
parent acaf136814
commit 423f683374
4 changed files with 179 additions and 1 deletions

53
input/day22.txt Normal file
View File

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

13
input/day22_example.txt Normal file
View File

@@ -0,0 +1,13 @@
Player 1:
9
2
6
3
1
Player 2:
5
8
4
7
10

110
src/day22.rs Normal file
View File

@@ -0,0 +1,110 @@
use super::util;
use std::collections::{VecDeque, HashSet};
pub fn solve() {
let lines = util::read_file("input/day22.txt");
let p1_cards = lines.iter().skip(1)
.take_while(|s| s != &"")
.map(|s| s.parse::<u32>().unwrap())
.collect();
let p2_cards = lines.iter().skip_while(|s| s != &"Player 2:")
.skip(1)
.map(|s| s.parse::<u32>().unwrap())
.collect();
let part1 = play_combat(&p1_cards, &p2_cards);
println!("Day 22 Part 1: {}", part1);
let part2 = play_recursive_combat(&p1_cards, &p2_cards);
println!("Day 22 Part 2: {}", part2.1);
}
fn play_combat(p1_cards: &Vec<u32>, p2_cards: &Vec<u32>) -> u32 {
let mut p1_stack = VecDeque::from(p1_cards.clone());
let mut p2_stack = VecDeque::from(p2_cards.clone());
loop {
let p1_card = p1_stack.pop_front();
if !p1_card.is_some() {
return calculate_score(&p2_stack);
}
let p2_card = p2_stack.pop_front();
if !p2_card.is_some() {
// Push the card back on the stack
p1_stack.push_front(p1_card.unwrap());
return calculate_score(&p1_stack);
}
if p1_card.unwrap() > p2_card.unwrap() {
p1_stack.push_back(p1_card.unwrap());
p1_stack.push_back(p2_card.unwrap());
} else {
p2_stack.push_back(p2_card.unwrap());
p2_stack.push_back(p1_card.unwrap());
}
}
}
fn play_recursive_combat(p1_cards: &Vec<u32>, p2_cards: &Vec<u32>) -> (u32, u32) {
let mut p1_stack = VecDeque::from(p1_cards.clone());
let mut p2_stack = VecDeque::from(p2_cards.clone());
let mut known_configurations = HashSet::new();
loop {
// TODO: Find a quick way to check if we already found this configuration before
if known_configurations.contains(&(&p1_stack, &p2_stack)) {
// Player 1 wins by infinite loop protection:
return (1, calculate_score(&p1_stack));
}
known_configurations.insert((p1_stack.clone(), p2_stack.clone()));
let p1_card = p1_stack.pop_front();
if !p1_card.is_some() {
return (2, calculate_score(&p2_stack));
}
let p2_card = p2_stack.pop_front();
if !p2_card.is_some() {
// Push the card back on the stack
p1_stack.push_front(p1_card.unwrap());
return (1, calculate_score(&p1_stack));
}
let winning_player;
if p1_card.unwrap() as usize <= p1_stack.len() && p2_card.unwrap() as usize <= p2_stack.len() {
// Let's play a recursive round:
let recursive_result = play_recursive_combat(
&p1_stack.iter().take(p1_card.unwrap() as usize).map(|n| n.clone()).collect(),
&p2_stack.iter().take(p2_card.unwrap() as usize).map(|n| n.clone()).collect::<Vec<u32>>());
winning_player = recursive_result.0;
} else {
if p1_card.unwrap() > p2_card.unwrap() {
winning_player = 1;
} else {
winning_player = 2;
}
}
if winning_player == 1 {
p1_stack.push_back(p1_card.unwrap());
p1_stack.push_back(p2_card.unwrap());
} else if winning_player == 2 {
p2_stack.push_back(p2_card.unwrap());
p2_stack.push_back(p1_card.unwrap());
} else {
panic!("No winner!");
}
}
}
fn calculate_score(stack: &VecDeque<u32>) -> u32 {
return stack.iter().rev().enumerate()
.map(|c| (c.0 + 1) as u32 * c.1)
.sum();
}

View File

@@ -22,8 +22,9 @@ mod day17;
mod day18;
mod day19;
mod day20;
mod day22;
const MAX_DAY: u8 = 20;
const MAX_DAY: u8 = 22;
const BENCHMARK_AMOUNT: u32 = 100;
fn solve(day: u8) {
@@ -48,6 +49,7 @@ fn solve(day: u8) {
18 => day18::solve(),
19 => day19::solve(),
20 => day20::solve(),
22 => day22::solve(),
_ => println!("This day is not yet implemented")
}
}