[TASK] Solved day 22 part 1 (part 2 partly solved)
This commit is contained in:
53
input/day22.txt
Normal file
53
input/day22.txt
Normal 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
13
input/day22_example.txt
Normal 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
110
src/day22.rs
Normal 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();
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user