[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 day18;
|
||||||
mod day19;
|
mod day19;
|
||||||
mod day20;
|
mod day20;
|
||||||
|
mod day22;
|
||||||
|
|
||||||
const MAX_DAY: u8 = 20;
|
const MAX_DAY: u8 = 22;
|
||||||
const BENCHMARK_AMOUNT: u32 = 100;
|
const BENCHMARK_AMOUNT: u32 = 100;
|
||||||
|
|
||||||
fn solve(day: u8) {
|
fn solve(day: u8) {
|
||||||
@@ -48,6 +49,7 @@ fn solve(day: u8) {
|
|||||||
18 => day18::solve(),
|
18 => day18::solve(),
|
||||||
19 => day19::solve(),
|
19 => day19::solve(),
|
||||||
20 => day20::solve(),
|
20 => day20::solve(),
|
||||||
|
22 => day22::solve(),
|
||||||
_ => println!("This day is not yet implemented")
|
_ => println!("This day is not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user