2020: day22: part 1

This commit is contained in:
Antoine Martin 2020-12-22 13:08:35 +01:00
parent fbd7ae5be2
commit fe1f56bd7d
6 changed files with 166 additions and 0 deletions

View file

@ -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
View 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

View 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
View 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);
}
}

View file

@ -20,3 +20,4 @@ pub mod day17;
pub mod day18;
pub mod day19;
pub mod day21;
pub mod day22;

View file

@ -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)