2020: day22: part 1
This commit is contained in:
parent
fbd7ae5be2
commit
fe1f56bd7d
|
@ -20,6 +20,7 @@ use aoc2020::day17;
|
|||
use aoc2020::day18;
|
||||
use aoc2020::day19;
|
||||
use aoc2020::day21;
|
||||
use aoc2020::day22;
|
||||
|
||||
fn aoc2020_all(c: &mut Criterion) {
|
||||
c.bench_function("day01", |b| b.iter(|| day01::run().unwrap()));
|
||||
|
@ -42,6 +43,7 @@ fn aoc2020_all(c: &mut Criterion) {
|
|||
c.bench_function("day18", |b| b.iter(|| day18::run().unwrap()));
|
||||
c.bench_function("day19", |b| b.iter(|| day19::run().unwrap()));
|
||||
c.bench_function("day21", |b| b.iter(|| day21::run().unwrap()));
|
||||
c.bench_function("day22", |b| b.iter(|| day22::run().unwrap()));
|
||||
}
|
||||
|
||||
criterion_group! {
|
||||
|
|
53
aoc2020/input/day22.txt
Normal file
53
aoc2020/input/day22.txt
Normal file
|
@ -0,0 +1,53 @@
|
|||
Player 1:
|
||||
43
|
||||
36
|
||||
13
|
||||
11
|
||||
20
|
||||
25
|
||||
37
|
||||
38
|
||||
4
|
||||
18
|
||||
1
|
||||
8
|
||||
27
|
||||
23
|
||||
7
|
||||
22
|
||||
10
|
||||
5
|
||||
50
|
||||
40
|
||||
45
|
||||
26
|
||||
15
|
||||
32
|
||||
33
|
||||
|
||||
Player 2:
|
||||
21
|
||||
29
|
||||
12
|
||||
28
|
||||
46
|
||||
9
|
||||
44
|
||||
6
|
||||
16
|
||||
39
|
||||
19
|
||||
24
|
||||
17
|
||||
14
|
||||
47
|
||||
48
|
||||
42
|
||||
34
|
||||
31
|
||||
3
|
||||
41
|
||||
35
|
||||
2
|
||||
30
|
||||
49
|
13
aoc2020/input/day22_provided.txt
Normal file
13
aoc2020/input/day22_provided.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
Player 1:
|
||||
9
|
||||
2
|
||||
6
|
||||
3
|
||||
1
|
||||
|
||||
Player 2:
|
||||
5
|
||||
8
|
||||
4
|
||||
7
|
||||
10
|
95
aoc2020/src/day22.rs
Normal file
95
aoc2020/src/day22.rs
Normal file
|
@ -0,0 +1,95 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Write;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
|
||||
const INPUT: &str = include_str!("../input/day22.txt");
|
||||
|
||||
pub fn run() -> Result<String> {
|
||||
let mut res = String::with_capacity(128);
|
||||
|
||||
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn play_game<'a>(deck_a: &'a mut Deck, deck_b: &'a mut Deck) -> &'a Deck {
|
||||
while !(deck_a.0.is_empty() || deck_b.0.is_empty()) {
|
||||
let card_a = deck_a.0.pop_front().unwrap();
|
||||
let card_b = deck_b.0.pop_front().unwrap();
|
||||
|
||||
match card_a.cmp(&card_b) {
|
||||
Ordering::Greater => {
|
||||
deck_a.0.push_back(card_a);
|
||||
deck_a.0.push_back(card_b);
|
||||
}
|
||||
Ordering::Less => {
|
||||
deck_b.0.push_back(card_b);
|
||||
deck_b.0.push_back(card_a);
|
||||
}
|
||||
Ordering::Equal => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
if deck_a.0.is_empty() {
|
||||
deck_b
|
||||
} else {
|
||||
deck_a
|
||||
}
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> Result<u64> {
|
||||
let mut decks = input.split("\n\n");
|
||||
|
||||
let mut deck_a: Deck = decks.next().context("couldn't get first deck")?.parse()?;
|
||||
let mut deck_b: Deck = decks.next().context("couldn't get second deck")?.parse()?;
|
||||
|
||||
let winning_deck = play_game(&mut deck_a, &mut deck_b);
|
||||
|
||||
Ok(winning_deck
|
||||
.0
|
||||
.iter()
|
||||
.rev()
|
||||
.enumerate()
|
||||
.map(|(i, card)| card * (i as u64 + 1))
|
||||
.sum())
|
||||
}
|
||||
|
||||
struct Deck(VecDeque<u64>);
|
||||
|
||||
impl Deck {}
|
||||
|
||||
impl std::str::FromStr for Deck {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
let mut lines = s.lines();
|
||||
|
||||
// `Player N:`
|
||||
lines.next().context("couldn't skip first line")?;
|
||||
|
||||
let deck = lines
|
||||
.map(|line| line.parse().map_err(anyhow::Error::new))
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
Ok(Self(deck))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const PROVIDED: &str = include_str!("../input/day22_provided.txt");
|
||||
|
||||
#[test]
|
||||
fn part1_provided() {
|
||||
assert_eq!(part1(PROVIDED).unwrap(), 306);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() {
|
||||
assert_eq!(part1(INPUT).unwrap(), 30780);
|
||||
}
|
||||
}
|
|
@ -20,3 +20,4 @@ pub mod day17;
|
|||
pub mod day18;
|
||||
pub mod day19;
|
||||
pub mod day21;
|
||||
pub mod day22;
|
||||
|
|
|
@ -22,6 +22,7 @@ use aoc2020::day17;
|
|||
use aoc2020::day18;
|
||||
use aoc2020::day19;
|
||||
use aoc2020::day21;
|
||||
use aoc2020::day22;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let days: &[DayFunc] = &[
|
||||
|
@ -45,6 +46,7 @@ fn main() -> Result<()> {
|
|||
day18::run,
|
||||
day19::run,
|
||||
day21::run,
|
||||
day22::run,
|
||||
];
|
||||
|
||||
aoc::run(days)
|
||||
|
|
Loading…
Reference in a new issue