mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 12:50:32 +01:00
Implementation day 22.
This commit is contained in:
@@ -7,7 +7,7 @@ use criterion::criterion_main;
|
||||
use criterion::BenchmarkId;
|
||||
use criterion::Criterion;
|
||||
|
||||
const DAYS_IMPLEMENTED: usize = 20;
|
||||
const DAYS_IMPLEMENTED: usize = 22;
|
||||
|
||||
fn read_input(day: usize) -> Vec<u8> {
|
||||
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 crate::common::Lines;
|
||||
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)]
|
||||
pub struct Day22;
|
||||
|
||||
impl Solution for Day22 {
|
||||
fn part1(&mut self, _input: &mut dyn Read) -> String {
|
||||
todo!()
|
||||
fn part1(&mut self, input: &mut dyn Read) -> String {
|
||||
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