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::day18;
|
||||||
use aoc2020::day19;
|
use aoc2020::day19;
|
||||||
use aoc2020::day21;
|
use aoc2020::day21;
|
||||||
|
use aoc2020::day22;
|
||||||
|
|
||||||
fn aoc2020_all(c: &mut Criterion) {
|
fn aoc2020_all(c: &mut Criterion) {
|
||||||
c.bench_function("day01", |b| b.iter(|| day01::run().unwrap()));
|
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("day18", |b| b.iter(|| day18::run().unwrap()));
|
||||||
c.bench_function("day19", |b| b.iter(|| day19::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("day21", |b| b.iter(|| day21::run().unwrap()));
|
||||||
|
c.bench_function("day22", |b| b.iter(|| day22::run().unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group! {
|
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 day18;
|
||||||
pub mod day19;
|
pub mod day19;
|
||||||
pub mod day21;
|
pub mod day21;
|
||||||
|
pub mod day22;
|
||||||
|
|
|
@ -22,6 +22,7 @@ use aoc2020::day17;
|
||||||
use aoc2020::day18;
|
use aoc2020::day18;
|
||||||
use aoc2020::day19;
|
use aoc2020::day19;
|
||||||
use aoc2020::day21;
|
use aoc2020::day21;
|
||||||
|
use aoc2020::day22;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let days: &[DayFunc] = &[
|
let days: &[DayFunc] = &[
|
||||||
|
@ -45,6 +46,7 @@ fn main() -> Result<()> {
|
||||||
day18::run,
|
day18::run,
|
||||||
day19::run,
|
day19::run,
|
||||||
day21::run,
|
day21::run,
|
||||||
|
day22::run,
|
||||||
];
|
];
|
||||||
|
|
||||||
aoc::run(days)
|
aoc::run(days)
|
||||||
|
|
Loading…
Reference in a new issue