2020: day17: part 1
This commit is contained in:
parent
8236dbc0c2
commit
e18b6edf80
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -68,6 +68,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"aoc",
|
"aoc",
|
||||||
|
"itertools",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -9,6 +9,7 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aoc = { path = "../aoc" }
|
aoc = { path = "../aoc" }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
|
itertools = "0.9"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
|
@ -16,6 +16,7 @@ use aoc2020::day13;
|
||||||
use aoc2020::day14;
|
use aoc2020::day14;
|
||||||
use aoc2020::day15;
|
use aoc2020::day15;
|
||||||
use aoc2020::day16;
|
use aoc2020::day16;
|
||||||
|
use aoc2020::day17;
|
||||||
|
|
||||||
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()));
|
||||||
|
@ -34,6 +35,7 @@ fn aoc2020_all(c: &mut Criterion) {
|
||||||
c.bench_function("day14", |b| b.iter(|| day14::run().unwrap()));
|
c.bench_function("day14", |b| b.iter(|| day14::run().unwrap()));
|
||||||
c.bench_function("day15", |b| b.iter(|| day15::run().unwrap()));
|
c.bench_function("day15", |b| b.iter(|| day15::run().unwrap()));
|
||||||
c.bench_function("day16", |b| b.iter(|| day16::run().unwrap()));
|
c.bench_function("day16", |b| b.iter(|| day16::run().unwrap()));
|
||||||
|
c.bench_function("day17", |b| b.iter(|| day17::run().unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
criterion_group! {
|
criterion_group! {
|
||||||
|
|
8
aoc2020/input/day17.txt
Normal file
8
aoc2020/input/day17.txt
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#####..#
|
||||||
|
#..###.#
|
||||||
|
###.....
|
||||||
|
.#.#.#..
|
||||||
|
##.#..#.
|
||||||
|
######..
|
||||||
|
.##..###
|
||||||
|
###.####
|
3
aoc2020/input/day17_provided.txt
Normal file
3
aoc2020/input/day17_provided.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.#.
|
||||||
|
..#
|
||||||
|
###
|
110
aoc2020/src/day17.rs
Normal file
110
aoc2020/src/day17.rs
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
|
|
||||||
|
use itertools::iproduct;
|
||||||
|
|
||||||
|
const INPUT: &str = include_str!("../input/day17.txt");
|
||||||
|
|
||||||
|
pub fn run() -> Result<String> {
|
||||||
|
let mut res = String::with_capacity(128);
|
||||||
|
|
||||||
|
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> Result<usize> {
|
||||||
|
let mut pocket_dim: PocketDimension = input.parse()?;
|
||||||
|
|
||||||
|
for _ in 0..6 {
|
||||||
|
pocket_dim.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(pocket_dim.points.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
type Point = (i64, i64, i64);
|
||||||
|
|
||||||
|
struct PocketDimension {
|
||||||
|
points: HashSet<Point>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PocketDimension {
|
||||||
|
fn neighbours(point: Point) -> impl Iterator<Item = Point> {
|
||||||
|
iproduct!(-1..=1, -1..=1, -1..=1)
|
||||||
|
.filter(|(x, y, z)| *x != 0 || *y != 0 || *z != 0)
|
||||||
|
.map(move |(dx, dy, dz)| (point.0 + dx, point.1 + dy, point.2 + dz))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn active_neighbours(&self, point: Point) -> usize {
|
||||||
|
Self::neighbours(point)
|
||||||
|
.filter(|p| self.points.contains(p))
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self) {
|
||||||
|
let mut processed: HashSet<Point> = HashSet::new();
|
||||||
|
let mut new = self.points.clone();
|
||||||
|
|
||||||
|
for point in &self.points {
|
||||||
|
for neighbour in Self::neighbours(*point).chain(std::iter::once(*point)) {
|
||||||
|
if processed.contains(&neighbour) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
processed.insert(neighbour);
|
||||||
|
|
||||||
|
// if point is active
|
||||||
|
if self.points.contains(&neighbour) {
|
||||||
|
if !(2..=3).contains(&self.active_neighbours(neighbour)) {
|
||||||
|
// now inactive
|
||||||
|
new.remove(&neighbour);
|
||||||
|
}
|
||||||
|
} else if self.active_neighbours(neighbour) == 3 {
|
||||||
|
new.insert(neighbour);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.points = new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::str::FromStr for PocketDimension {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self> {
|
||||||
|
let points = s
|
||||||
|
.lines()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(i, line)| {
|
||||||
|
line.chars().enumerate().filter_map(move |(j, c)| match c {
|
||||||
|
'#' => Some(Ok((i as i64, j as i64, 0))),
|
||||||
|
'.' => None,
|
||||||
|
_ => Some(Err(anyhow!("unexpected char: `{}`", c))),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Result<_>>()?;
|
||||||
|
|
||||||
|
Ok(Self { points })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const PROVIDED: &str = include_str!("../input/day17_provided.txt");
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_provided() {
|
||||||
|
assert_eq!(part1(PROVIDED).unwrap(), 112);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_real() {
|
||||||
|
assert_eq!(part1(INPUT).unwrap(), 336);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,3 +16,4 @@ pub mod day13;
|
||||||
pub mod day14;
|
pub mod day14;
|
||||||
pub mod day15;
|
pub mod day15;
|
||||||
pub mod day16;
|
pub mod day16;
|
||||||
|
pub mod day17;
|
||||||
|
|
|
@ -18,6 +18,7 @@ use aoc2020::day13;
|
||||||
use aoc2020::day14;
|
use aoc2020::day14;
|
||||||
use aoc2020::day15;
|
use aoc2020::day15;
|
||||||
use aoc2020::day16;
|
use aoc2020::day16;
|
||||||
|
use aoc2020::day17;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let days: &[DayFunc] = &[
|
let days: &[DayFunc] = &[
|
||||||
|
@ -37,6 +38,7 @@ fn main() -> Result<()> {
|
||||||
day14::run,
|
day14::run,
|
||||||
day15::run,
|
day15::run,
|
||||||
day16::run,
|
day16::run,
|
||||||
|
day17::run,
|
||||||
];
|
];
|
||||||
|
|
||||||
aoc::run(days)
|
aoc::run(days)
|
||||||
|
|
Loading…
Reference in a new issue