mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implementation day 22.
This commit is contained in:
@@ -7,7 +7,7 @@ use criterion::criterion_main;
|
|||||||
use criterion::BenchmarkId;
|
use criterion::BenchmarkId;
|
||||||
use criterion::Criterion;
|
use criterion::Criterion;
|
||||||
|
|
||||||
const DAYS_IMPLEMENTED: usize = 20;
|
const DAYS_IMPLEMENTED: usize = 22;
|
||||||
|
|
||||||
fn read_input(day: usize) -> Vec<u8> {
|
fn read_input(day: usize) -> Vec<u8> {
|
||||||
let input_path = format!("inputs/{:02}.txt", day);
|
let input_path = format!("inputs/{:02}.txt", day);
|
||||||
|
|||||||
53
2020/inputs/22.txt
Normal file
53
2020/inputs/22.txt
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
Player 1:
|
||||||
|
26
|
||||||
|
14
|
||||||
|
6
|
||||||
|
34
|
||||||
|
37
|
||||||
|
9
|
||||||
|
17
|
||||||
|
39
|
||||||
|
4
|
||||||
|
5
|
||||||
|
1
|
||||||
|
8
|
||||||
|
49
|
||||||
|
16
|
||||||
|
18
|
||||||
|
47
|
||||||
|
20
|
||||||
|
31
|
||||||
|
23
|
||||||
|
19
|
||||||
|
35
|
||||||
|
41
|
||||||
|
28
|
||||||
|
15
|
||||||
|
44
|
||||||
|
|
||||||
|
Player 2:
|
||||||
|
7
|
||||||
|
2
|
||||||
|
10
|
||||||
|
25
|
||||||
|
29
|
||||||
|
46
|
||||||
|
40
|
||||||
|
45
|
||||||
|
11
|
||||||
|
50
|
||||||
|
42
|
||||||
|
24
|
||||||
|
38
|
||||||
|
13
|
||||||
|
36
|
||||||
|
22
|
||||||
|
33
|
||||||
|
3
|
||||||
|
43
|
||||||
|
21
|
||||||
|
48
|
||||||
|
30
|
||||||
|
32
|
||||||
|
12
|
||||||
|
27
|
||||||
13
2020/samples/22.txt
Normal file
13
2020/samples/22.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Player 1:
|
||||||
|
9
|
||||||
|
2
|
||||||
|
6
|
||||||
|
3
|
||||||
|
1
|
||||||
|
|
||||||
|
Player 2:
|
||||||
|
5
|
||||||
|
8
|
||||||
|
4
|
||||||
|
7
|
||||||
|
10
|
||||||
@@ -1,12 +1,122 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
|
use crate::common::Lines;
|
||||||
use crate::Solution;
|
use crate::Solution;
|
||||||
|
|
||||||
|
type Deck = VecDeque<u32>;
|
||||||
|
|
||||||
|
fn read_input(input: &mut dyn Read) -> (Deck, Deck) {
|
||||||
|
let mut lines = Lines::new(input).skip(1);
|
||||||
|
|
||||||
|
let mut player1 = VecDeque::new();
|
||||||
|
|
||||||
|
while let Some(line) = lines.next() {
|
||||||
|
if line.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
player1.push_back(line.parse().unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let player2 = lines.skip(1).map(|l| l.parse().unwrap()).collect();
|
||||||
|
|
||||||
|
(player1, player2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn play_recursive_game(mut p1: Deck, mut p2: Deck) -> (bool, Deck) {
|
||||||
|
let mut seen = HashSet::new();
|
||||||
|
|
||||||
|
while !p1.is_empty() && !p2.is_empty() {
|
||||||
|
if !seen.insert((p1.clone(), p2.clone())) {
|
||||||
|
return (true, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let v1 = p1.pop_front().unwrap();
|
||||||
|
let v2 = p2.pop_front().unwrap();
|
||||||
|
|
||||||
|
let p1_wins = if v1 as usize <= p1.len() && v2 as usize <= p2.len() {
|
||||||
|
let p1_copy = p1.iter().take(v1 as usize).copied().collect();
|
||||||
|
let p2_copy = p2.iter().take(v2 as usize).copied().collect();
|
||||||
|
|
||||||
|
play_recursive_game(p1_copy, p2_copy).0
|
||||||
|
} else {
|
||||||
|
v1 > v2
|
||||||
|
};
|
||||||
|
|
||||||
|
if p1_wins {
|
||||||
|
p1.push_back(v1);
|
||||||
|
p1.push_back(v2);
|
||||||
|
} else {
|
||||||
|
p2.push_back(v2);
|
||||||
|
p2.push_back(v1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if p1.is_empty() {
|
||||||
|
(false, p2)
|
||||||
|
} else {
|
||||||
|
(true, p1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn score(winner: Deck) -> u32 {
|
||||||
|
winner
|
||||||
|
.into_iter()
|
||||||
|
.rev()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(pos, val)| (pos as u32 + 1) * (val as u32))
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Day22;
|
pub struct Day22;
|
||||||
|
|
||||||
impl Solution for Day22 {
|
impl Solution for Day22 {
|
||||||
fn part1(&mut self, _input: &mut dyn Read) -> String {
|
fn part1(&mut self, input: &mut dyn Read) -> String {
|
||||||
todo!()
|
let (mut p1, mut p2) = read_input(input);
|
||||||
|
|
||||||
|
while !p1.is_empty() && !p2.is_empty() {
|
||||||
|
let v1 = p1.pop_front().unwrap();
|
||||||
|
let v2 = p2.pop_front().unwrap();
|
||||||
|
|
||||||
|
if v1 > v2 {
|
||||||
|
p1.push_back(v1);
|
||||||
|
p1.push_back(v2);
|
||||||
|
} else {
|
||||||
|
p2.push_back(v2);
|
||||||
|
p2.push_back(v1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let winner = if p1.is_empty() { p2 } else { p1 };
|
||||||
|
|
||||||
|
score(winner).to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(&mut self, input: &mut dyn Read) -> String {
|
||||||
|
let (p1, p2) = read_input(input);
|
||||||
|
|
||||||
|
score(play_recursive_game(p1, p2).1).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::test_implementation;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const SAMPLE: &[u8] = include_bytes!("../samples/22.txt");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part1() {
|
||||||
|
test_implementation!(Day22, 1, SAMPLE, 306);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part2() {
|
||||||
|
test_implementation!(Day22, 2, SAMPLE, 291);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user