wip day 20

test passes, but real input is wrong
This commit is contained in:
kageru 2021-12-20 15:31:46 +01:00
parent a2c61d1bf4
commit 549ee502b1
4 changed files with 237 additions and 28 deletions

102
2021/inputs/day20 Normal file
View File

@ -0,0 +1,102 @@
#.#..#.#...##.###.##.#.###....#..##..#.#####.#.##.#.##..##..#.#.######..##..####.#....#.#....##....#####..#######..###..#.##..#....#....#....#..#..#..##...####..###.##..##..#.#.#.#.#.#.#..##.###.##.#.##.#.##.#####..###.#.#...##..##...###...###..##...##.######....####.###...####.##.....###.##.#.##.#.....##.##..###.....#..##....#.##.#...##.###.###.#..####....#.###...#....#..###...##..#####..#.######..#.#....####.####.#.#....#.###..##...#.###.####....#.##.#....##...##.#..#....#.##...#....#.####..#.#..####.#...
####.#.#####..#.#####..###.###...##...##.#.##.###..#...#......##.##..##.####.........#..##...#.####.
#.#.###...###.####....##..##......##.#.####...#########.#.###.#.#.#..###..##...###.###.#.######.#.#.
##...#.#..##.#.##...#..##.####.###.###..###...#####.##.#..##.#.#####.###...#.###.....#######..##...#
####..#.###..####..##...#..######.##.#...#.#..#...#.##..####...##...#.#.#.##.##......##.##.#.##.....
.#########.###.###..#......##.###.####.#..###.#.##.####.#..###....##.##.##.#..##..#..##..#.##.#.#...
..#.#.#...#.###...##..#.#....#.###..#.##...#.#....#.##.#.##.##..###.##.####..#.###.#.####..##....###
.##....#.#.##.....####..#..##...#..............#...###.####....#..#....##.####..###....##...#.###.##
.#.########..###.#..###.#..###.#.##.#.#.#.###...##..##.#.#..#..##.#......###.###..#.##.####.....#...
...###.#...#.##..#...##..###...###...#....#..#.#######...#..##..###.#.#......#.#..###..#.#.###.#..##
..#####...##.##.....#.#####....#..#.#......#.#.#....####.##..#.##.##..##.#########.##.###...###...##
#...#...#####....##.#.#.###......##.#####.#.###.#.#.#.####...##.#..#.#.#..#.#..####..##...#.#....#..
.#..#.##.#.#.##.#..#.######.#.#....#.##.#..#.#.##...####..##.##..####.####.#...#...#####.#....####..
.....#.##..#.#.###.##....##....##.##.#...###.#.#..#.##.###.#...#...#.#####..#.##.....#...#.#.#.#....
....##.##...##..##.########...###...###..###..#..#...####..#..#..####.#..#.#.....###.#..#.#...#..#..
...#.#.#.###...#...#####.#....##..####..##.####.#..###..#.##.###...#...#..#.##...##.#...#.....###...
##....#..#.#...#.......#.##.######....#..##.##..#...###.#..###..#.#..##.#.........##..###.#......#.#
###...#########.#....###...#.#...#.#..#..##.##.#..#.#......##.#.##.#....#########...#.#.##..########
.###...#######.#......####.#.##.###.##.#..##.###.##..########.#..##.##..#..#..#...#.#..###..##...###
..#...##.....#.#..###.#..#.##.#..#.#.#.##.#####....####.#.#..#...##.##.##.#..####.#..#.#####......#.
#...##..##########.......#.....##.####..#####..##...#...##..###.#.#.#.#.#####.####.##.##.#.#.....###
.#.###.#..#..###.#..#.#.#....#.#####.##....#.#.#..##.#.#.#.###.#..#..##..#..###....#...##.#..#.#.#.#
...###.#..#....##.#...#...#..#....###...#.....#..####.##..#.###...#....###..##.#.##...#..##..#.##.#.
#.#.###.#..#....##.#..#####..###...##.##...#...###.#.##.#.#.#...#.#.#....####..#.##..##...#.#.##...#
.#..#..#..##########.#.###.#..##..##.#.##.#..#.##..#..#.#.##....##..##....##.######..#....#.#..#####
...#.##.#.###.#..#####.#........#.#.####.##..##..#.#..##...#..#..#..#.#.#.#..#..#.###..#..#.####.###
.###...###.#..#..#....##.#.##.#.....#..#.#.#...##.##.#...####..##..#.#..#...#....###.#..#####.#####.
...#.#.##.#......#.#....#####..#.#..##..#.#.#..###.##...#..#..##...#...#######.###.#####.###...#....
.##....#...###..####....#.#..##.#.#.##..###########...#.###..#.##.##.##.#....##.##..####......###...
#.##......#.##.###.##...##..#.##.#.##.##..#..#.#####....##.##.###.#########.#..###.....#....##..##.#
#.####.#.#...#.#.#.##..##.###..###.#..#..#####...####.####....#.##...####..#######.#....#######.#.#.
##...#..#...##...#.#...#.##.#......#.#.#.....#.#.#....#.#.#...#.#.#######.##.#.#..##..#....#.#..#..#
#..##..#.#..#.#..#.#.#.#.#....#.#.##.##.#.##.....##...##...##.#####.#.###.#..#..####.#.#..#######.#.
.#.##..#.##..#....##.#.#..#..##..##...#...######.###....#..#...##..#.#..........#.######.........#..
###.#.#..#.#..#.#.#.##..######.#.......###.###.#..#....#.##.#####.#.###.##.####.#.##..##.##.####.#..
##.#...#.....#...##.##.##....########......#.#.#...#.#..#.#....###...##.##...........####.##.##..#.#
####.###.#.#...#.##....#.##..###..#.#.#####..####.#.#..#..#....#...#..#...##...#..#.###..###..#.#.##
#.#..#..#.###....##.#..##.#..#...##..##..#.#.#.#..#...##.######..#.#..####.#.###..####..##...#.#...#
.###...#...#####...#.#...#.##..#...###.##.###...#..#.#.#.#...#.##.##.##.##.##...#...#.###.#.#......#
#.......#.#....####.....#..#.#.#..##.#####..##..#..###.#..#..##...####....##.#.#..###...#.##.#.###..
#.#..#.#.##.#.#####.#######.#####.#..###..#.#.......#.##...#..##..##....#.#..######.....##.##..##.##
#####.#....######.....##.#...#..##....#...###.##..#..##..###.###..###.####..#...#######....######...
#####.........#....#....#..#####.###.#..#.#....##.##..###..#..#.#...#.##...#.#..##..#.#.###.####.#.#
...###.#####.#.##..###.....#.#.......##...#....#.#.##.#......#.#...#.#..#...#.####.######.##...##.##
#...#..#..#..#...##.#.....#.#.##..####..##.#..#.#.#####.#.##.###.#....###...######........#..#..##..
..##.......##.##.#....###.#...#...#.##.###..###.#..####.#.######.#..#######.......#.##..#.####...#.#
......##.##..#####.##....#..#..##.#...#...####..##...##.##.#....#....#.#.###.....##..##.#...##....#.
####...#......#.#........##.#..#...#.#.###..#....##.###.#..#.#.##.##......#.#...#.##...##.###..#.###
.##....##..##.########.##..##..#.#.....#..#...#.#.#.#..#.##..#.##.#..#.#....####......#..#...#.#.#..
.##.#...#.##.##.#.#..###..#.#...##.#.#.#.##..#..######..##.#.##....###.#....##..#.###.##.##..#...#.#
..#.#.#...#...###..##....#.##..#..#...#....#.#...#####...##.####.#.#...#..#.##.###...#...#..#.##....
...#.####.###.#...#####..####.####..#.##...########...#.#...#.##.#.#..##.#..#..##.###.#####..##.##.#
##.#.#..##.###.##.#......###.#..#.#..#.#...#.#.#...#.##.###.#####.##..##...##.#..#..#.....#.###....#
......##.#..###....#.#####.###.###.###...#.....####.###.........#....###.####.#.......#..#........#.
...####.##....#.#.#.#.##..#..#.#..##....#...##..#...#.#..#.####..#.##.##.##......###..#...####..#.##
##.#.#####.....#...####.##.#.#.####.#......#.######...######.##.######....##..######..##.#...##.#..#
..#.##.......#.#####.#......###.###.##..####.#.###....#.###.#..#..#########..#..#..##.##.#....#....#
....####...#.#.#...####.#.#..###...#...#..##.##..####.#.#..##.#.#.#.###...........##..##..####.####.
#.#..###..######..##.##..#...#.#####......#.....######.##..#.#####...##..####.###.#..######...#.###.
..#####.#..#...#.####.###.#..##....####.#.#.#.#.##.####.#.##.###.###...#..#...#.##..##...#.....#....
..#.##.#..##....####.#.....##.##...##.#.#.####.##.#..####...###..#.#.######.#.###..#..#...#....##.##
#...##.#...#.###...#.##...#.#..###.#####.#....#########....##.#..###..##......#.#.........#.#...##.#
##..##.#.#...#..#..#####..#.#....#...###.##..#.####..#......##..##..##..#....#..#####.#.#.####.##..#
#.###...###..#.......#.#.##.##..###.####...##.##.#..#.#..#..#.###...#..######......##...##.##.#..#.#
.####.#...##.#..#...#.###..##.#..##.....###..###..##.####...#....#######.#.############.##.....##.##
#..####.#..#........##.#.#.#####.#.#.#.#.##.#..#...#..##...#...#.#..##.###.#.#######.#.#####..#.###.
#######...#####.#.##..####.#......##.#..#.###.####.#......####.#.##.#..##...#.....#.##.####.##.....#
#.....#......##...#.#.##.####.######...#.....#..##..##.####....##..##..#.#.##..###.##...#.##..#..###
....##.#..#.#..##.####.#.##..##.#.##.##.#..##########.#..##.....##....#.##.#...#.#..#..#..#.#.#.###.
#......###......###.#.#.#..##....##..##..##.#..#.#.####.####...##.#...##.####..#.....#...#.#.#####..
###..###.#...#..###.#......####.##.#.#.###...#..........##......####.###.###.#..#.....#####..####.##
..#.####..#...##.###...####.##.......#.##.##.#.#.#.##....#..###.....#....###.#..#...######.#...#..#.
#..#..#.#..#...#.#.###.####.##........#.##.####..#..############.#.###...###.#######.#.#....#...###.
#.######.###.##.#..#####.#.#....##.#.##..#######..##...##...#...##..##...#.##.##.#####...##.#...##..
##.###.###..##..##.#.#.##..#...#.#...##.#.........#.#.#.......###...#.##..#.##.#.##.####...##...###.
..#.##..####.##...##....###.#...#..#..##.##..###..###.###...#.#.#.####..#.#.##...#.#..####...#..##.#
#.#.#..#....#.#.#.#......#..#..#...#.#...#...#..#..#.##..#..#....#.##..#..#...##.######..#..##.#####
.#..##..#.#...#..#..##....##.....#....##.#..######...##.##.......#.#.....#####.####.#.##.#.#.##.###.
##.#..##.#...#..#.####...###..##.#####....#..#...#.##...#.#..###...####.#.##....#..#.#.##.#..####...
#.#######...##.####..#...#...##.#.###..#..###.#.#..#.###.#.##.#.###....#.##..###..#.#.########......
###.##.###.#...##....#.#..##.###.#..#.#.##.#.##....#.#####...###..###..#..##..#..#.#..#####.###..#..
.###.###.##..##..#######.##########.#.###.#.#.#....#..#.###...##.##.....#..#....###.....#....##...##
##...###.##.##....#.#....#####..#.######.##.#########..#.#...#.##....#.####.#.###.##.####.#.#.#####.
###.###.....##.###.#..##.#...#......#.###.#..##.#...###..##.#.#.#...###.#.#...##..##....#####....##.
#.#..#..###.##.##.##....#..###.#.###..#######.#...####..#####..#.......#..#.#.##.#..##..#.####..##.#
..##....##...###.###...#.###.....####.#..###.#.........#....####.#..#.#.##...#...###...#.##.....###.
.#..#.##.#.#.#.#.#..###.#..#.#.#######.####.###..#.#.##.......##.#...#...##..##.##.#.#..##.###.###..
#.#..#...#...###.#.#....#..#..###.#####.#.#.#..##.#.#........###.#.#...#.....#..###..##.##..###..#..
....#.#..#..##..#....###....#....###..##...#.#....#.###.####..#.#.##.####.#..#..##.....#.##.#...#.#.
...#..#.#.#..#.###...###...####..#....###.##.#..###.##.#.#.#.##...#...#.#...##....#.#.##.#.##..#.#..
##.#..###...#...##..#....###.#.##....##.#.##.#.##....####..#...#.#####.....#.##.#..#.#.###.#....#..#
#.#.##..#..##.##..##.##.#####.####..#..#..#....###.##.#..#####.##.#####..######.#...#...#..#.#..###.
..#.#......#..##.#...#.#..###..####.##.##..#..#####.##....#.##.....###.###........##.......##.#.####
##..##.#.#.#..##..#.#.#..##.#.######...##..##...##..#####.#...#.#.....###.#...##....#...#.#.#...###.
#......#.###.##.#####..##.#..#.#...######....#..#....#...#####.#.#.#.#.#...####..#...#.....#..#.#.##
..##.##..####...##.#...##...#####...#...#.##.###..#....####.#..#..#.####.##..##.#..####..#.#..####..
#####.#...#.##..##.#..####.#.#..#.#....#.####.#.####..#..####...#.#..##.#.#....#####..#..####..#...#
..#.......##.#..##.#..#..#.######.#...#.....###.###.####..#.#....#..#...#.#..#..##...#.##.#######.##
#.##..##..#.#.#####.........###..##.#.#...###.#.###...###.#...###..##..#.###..#.#.#....####...##....
##....#.##.##.#..###...#.#.##..#.#......#...#.#.#.#.#..###.#.....#.##.##..#.###..##..###.##....#####
...#.#..#...#..##...##....##....#.#..###..#....#..#.#.###.....##....#..#....##.###....#.#..#.#.#.#..

114
2021/src/bin/day20.rs Normal file
View File

@ -0,0 +1,114 @@
#![feature(derive_default_enum)]
#![feature(test)]
extern crate test;
use std::fmt;
use aoc2021::{
common::*,
grid::{draw_ascii, get_boundaries, Boundaries, Grid, HashGrid, Position2D},
};
use itertools::Itertools;
#[derive(Debug, PartialEq, Default, Clone, Copy)]
enum Pixel {
Bright,
#[default]
Dark,
}
#[rustfmt::skip]
impl fmt::Display for Pixel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", match self { Pixel::Bright => '#', Pixel::Dark => '.' })
}
}
impl From<u8> for Pixel {
fn from(b: u8) -> Self {
match b {
b'#' => Pixel::Bright,
b'.' => Pixel::Dark,
_ => unreachable!(),
}
}
}
const DAY: usize = 20;
type Parsed = ([Pixel; 512], HashGrid<Pixel, 2>);
fn parse_input(raw: &str) -> Parsed {
let (enhance, image) = raw.split_once("\n\n").unwrap();
// type inference on these methods is absolute magic
(enhance.bytes().map_into().collect_vec().try_into().unwrap(), HashGrid::from_bytes_2d(image, Pixel::from))
}
fn neighbors_plus_self(p: Position2D) -> Vec<Position2D> {
(-1..=1)
.rev() // my grid has (0,0) at top left which doesn’t seem to match the task
.flat_map(|x| (-1..=1).rev().map(move |y| Position2D::from([y, x])))
.map(|offset| p + offset)
.collect()
}
fn part1((lookup, grid): &Parsed) -> usize {
let mut grid = grid.to_owned();
for _ in 0..2 {
// println!("{}\n{}\n\n", grid.len(), draw_ascii(&grid.fields));
grid = step(grid, lookup);
}
// println!("{}\n{}\n\n", grid.len(), draw_ascii(&grid.fields));
grid.fields.values().filter(|&&p| p == Pixel::Bright).count()
}
fn step(grid: HashGrid<Pixel, 2>, lookup: &[Pixel; 512]) -> HashGrid<Pixel, 2> {
let Boundaries { x_min, x_max, y_min, y_max } = get_boundaries(&grid.fields.keys().collect_vec());
println!("{x_min}, {x_max}, {y_min}, {y_max}");
(x_min - 1..=x_max + 1)
.flat_map(|x| (y_min - 1..=y_max + 1).map(move |y| Position2D::from([x, y])))
.map(|p| (p, lookup[lookup_index(p, &grid)]))
.collect()
}
fn lookup_index(p: Position2D, grid: &HashGrid<Pixel, 2>) -> usize {
let idx =
neighbors_plus_self(p).into_iter().rev().map(|p| grid.get(&p) == Some(&Pixel::Bright)).fold(0, |acc, n| (acc << 1) | n as usize);
idx
}
fn part2(parsed: &Parsed) -> usize {
unimplemented!()
}
fn main() {
let input = parse_input(&read_file(DAY));
println!("Part 1: {}", part1(&input));
println!("Part 2: {}", part2(&input));
}
#[cfg(test)]
mod tests {
use super::*;
use aoc2021::*;
const TEST_INPUT: &str = "..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
#..#.
#....
##..#
..#..
..###";
#[test]
fn lookup_index_test() {
let grid = HashGrid::from_bytes_2d("...\n#..\n.#.", Pixel::from);
let p = Position2D::from([1, 1]);
let idx = lookup_index(p, &grid);
assert_eq!(idx, 34);
}
test!(part1() == 35);
test!(part2() == 0);
// bench!(part1() == 5573); // too high
bench!(part2() == 0);
bench_input!(|(_, g): &Parsed| g.len() => 10_000);
}

View File

@ -2,7 +2,7 @@ pub mod cell;
pub mod direction;
pub mod position;
pub use direction::*;
use itertools::join;
use itertools::{join, Itertools, MinMaxResult};
pub use position::*;
use std::{collections::HashMap, fmt::Display, hash::BuildHasher};
@ -34,7 +34,7 @@ impl<T: Default, const D: usize> Grid<T, D> for HashGrid<T, D> {
}
}
impl<T: Default + Copy, const D: usize> HashGrid<T, D> {
impl<T: Default + Copy> HashGrid<T, 2> {
pub fn from_bytes_2d<F: FnMut(u8) -> T + Copy>(raw: &str, mut f: F) -> HashGrid<T, 2> {
raw.lines()
.enumerate()
@ -75,18 +75,24 @@ impl<T: Copy> VecGrid<T> {
}
}
struct Boundaries {
x_min: i64,
x_max: i64,
y_min: i64,
y_max: i64,
pub struct Boundaries {
pub x_min: i64,
pub x_max: i64,
pub y_min: i64,
pub y_max: i64,
}
fn get_boundaries(input: &[&PositionND<2>]) -> Boundaries {
let x_min = input.iter().min_by_key(|k| k.points[0]).map(|p| p.points[0]).unwrap_or(0);
let x_max = input.iter().max_by_key(|k| k.points[0]).map(|p| p.points[0]).unwrap_or(0);
let y_min = input.iter().min_by_key(|k| k.points[1]).map(|p| p.points[1]).unwrap_or(0);
let y_max = input.iter().max_by_key(|k| k.points[1]).map(|p| p.points[1]).unwrap_or(0);
pub fn get_boundaries(input: &[&PositionND<2>]) -> Boundaries {
let (x_min, x_max) = match input.iter().map(|p| p.points[0]).minmax() {
MinMaxResult::NoElements => (0, 0),
MinMaxResult::MinMax(min, max) => (min, max),
MinMaxResult::OneElement(x) => (x, x),
};
let (y_min, y_max) = match input.iter().map(|p| p.points[1]).minmax() {
MinMaxResult::NoElements => (0, 0),
MinMaxResult::MinMax(min, max) => (min, max),
MinMaxResult::OneElement(x) => (x, x),
};
Boundaries { x_min, x_max, y_min, y_max }
}

View File

@ -6,38 +6,25 @@ use std::{
ops::{Add, Mul, Sub},
};
pub trait Position
where Self: Sized + Hash + PartialEq + Eq + Clone + Copy
{
fn neighbors(&self) -> Vec<Self>;
}
#[derive(Hash, PartialEq, Eq, Debug, Clone, Copy)]
pub struct PositionND<const DIMS: usize> {
pub points: [i64; DIMS],
}
pub type Position2D = PositionND<2>;
impl<I, const D: usize> From<[I; D]> for PositionND<D>
where I: TryInto<i64> + Copy
{
fn from(s: [I; D]) -> Self {
let mut points = [0; D];
for i in 0..D {
points[i] = unwrap_number_result(s[i]);
points[i] = s[i].try_into().unwrap_or_else(|_| panic!("number did not fit in target type"))
}
Self { points }
}
}
// because calling .unwrap() on a TryInto result isn’t possible without trait bounds on the
// associated Error type.
fn unwrap_number_result<I: TryInto<i64>>(i: I) -> i64 {
match i.try_into() {
Ok(i) => i,
_ => panic!("Bad coordinate"),
}
}
pub const fn num_neighbors(d: usize) -> usize {
3usize.pow(d as u32) - 1
}