From 18202694cfc4c715de7dab36639373f9deb1abe3 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sun, 25 Dec 2022 00:43:42 -0500 Subject: day 22 part 1 --- src/bin/2022/day22.rs | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/bin/2022/main.rs | 18 ++--- src/grid.rs | 112 ++++++++++++++++++++----------- src/parse.rs | 2 +- 4 files changed, 265 insertions(+), 48 deletions(-) create mode 100644 src/bin/2022/day22.rs (limited to 'src') diff --git a/src/bin/2022/day22.rs b/src/bin/2022/day22.rs new file mode 100644 index 0000000..81bf264 --- /dev/null +++ b/src/bin/2022/day22.rs @@ -0,0 +1,181 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use advent_of_code::prelude::*; + +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug, Default)] +enum Tile { + Open, + Wall, + #[default] + Noop, +} + +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +enum Step { + Forward(usize), + Left, + Right, +} + +#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] +enum Direction { + Right, + Down, + Left, + Up, +} + +impl std::convert::From for usize { + fn from(direction: Direction) -> Self { + match direction { + Direction::Right => 0, + Direction::Down => 1, + Direction::Left => 2, + Direction::Up => 3, + } + } +} + +impl Direction { + fn left(&self) -> Self { + match self { + Direction::Right => Direction::Up, + Direction::Down => Direction::Right, + Direction::Left => Direction::Down, + Direction::Up => Direction::Left, + } + } + + fn right(&self) -> Self { + match self { + Direction::Right => Direction::Down, + Direction::Down => Direction::Left, + Direction::Left => Direction::Up, + Direction::Up => Direction::Right, + } + } +} + +#[derive(Debug)] +pub struct Map { + grid: Grid, + path: Vec, +} + +impl Map { + fn step(&self, pos: (Row, Col), facing: Direction) -> (Row, Col) { + let (row_diff, col_diff, sub) = match facing { + Direction::Right => (0, 1, false), + Direction::Down => (1, 0, false), + Direction::Left => (0, 1, true), + Direction::Up => (1, 0, true), + }; + let rows = self.grid.rows().0; + let cols = self.grid.cols().0; + let mut new_pos = pos; + new_pos = ( + if sub { + rows + new_pos.0 - row_diff + } else { + rows + new_pos.0 + row_diff + } % rows, + if sub { + cols + new_pos.1 - col_diff + } else { + cols + new_pos.1 + col_diff + } % cols, + ); + while matches!(self.grid[new_pos.0][new_pos.1], Tile::Noop) { + new_pos = ( + if sub { + rows + new_pos.0 - row_diff + } else { + rows + new_pos.0 + row_diff + } % rows, + if sub { + cols + new_pos.1 - col_diff + } else { + cols + new_pos.1 + col_diff + } % cols, + ); + } + if matches!(self.grid[new_pos.0][new_pos.1], Tile::Wall) { + pos + } else { + new_pos + } + } +} + +pub fn parse(fh: File) -> Result { + let mut lines = parse::raw_lines(fh); + let grid = parse::grid(parse::chunk(&mut lines), |c, _, _| match c { + b' ' => Tile::Noop, + b'.' => Tile::Open, + b'#' => Tile::Wall, + _ => panic!("invalid map tile {}", c), + }); + + let path_str = lines.next().unwrap(); + let mut path_str = &path_str[..]; + let mut path = vec![]; + while let Some(first) = path_str.chars().next() { + match first { + 'R' => { + path.push(Step::Right); + path_str = &path_str[1..]; + } + 'L' => { + path.push(Step::Left); + path_str = &path_str[1..]; + } + '0'..='9' => { + let prefix_len = path_str + .chars() + .take_while(|c| ('0'..='9').contains(c)) + .count(); + path.push(Step::Forward( + path_str[0..prefix_len].parse().unwrap(), + )); + path_str = &path_str[prefix_len..]; + } + _ => panic!("invalid path char {}", first), + } + } + + Ok(Map { grid, path }) +} + +pub fn part1(map: Map) -> Result { + let mut pos = (Row(0), Col(0)); + let mut facing = Direction::Right; + for step in &map.path { + match step { + Step::Left => facing = facing.left(), + Step::Right => facing = facing.right(), + Step::Forward(n) => { + for _ in 0..*n { + pos = map.step(pos, facing); + } + } + } + } + Ok((pos.0 .0 + 1) * 1000 + (pos.1 .0 + 1) * 4 + usize::from(facing)) +} + +pub fn part2(map: Map) -> Result { + todo!() +} + +#[test] +fn test() { + assert_eq!( + part1(parse(parse::data(2022, 22).unwrap()).unwrap()).unwrap(), + 95358 + ); + // assert_eq!( + // part2(parse(parse::data(2022, 22).unwrap()).unwrap()).unwrap(), + // 0 + // ); +} diff --git a/src/bin/2022/main.rs b/src/bin/2022/main.rs index 46cc3bb..efc7b22 100644 --- a/src/bin/2022/main.rs +++ b/src/bin/2022/main.rs @@ -14,14 +14,6 @@ use advent_of_code::prelude::*; mod day1; mod day10; mod day11; -mod day2; -mod day3; -mod day4; -mod day5; -mod day6; -mod day7; -mod day8; -mod day9; mod day12; mod day13; mod day14; @@ -30,11 +22,20 @@ mod day16; mod day17; mod day18; mod day19; +mod day2; mod day20; mod day21; +mod day22; mod day23; mod day24; mod day25; +mod day3; +mod day4; +mod day5; +mod day6; +mod day7; +mod day8; +mod day9; // NEXT MOD #[paw::main] @@ -62,6 +63,7 @@ fn main(opt: Opt) -> Result<()> { 19 => advent_of_code::day!(2022, opt.day, opt.puzzle, day19), 20 => advent_of_code::day!(2022, opt.day, opt.puzzle, day20), 21 => advent_of_code::day!(2022, opt.day, opt.puzzle, day21), + 22 => advent_of_code::day!(2022, opt.day, opt.puzzle, day22), 23 => advent_of_code::day!(2022, opt.day, opt.puzzle, day23), 24 => advent_of_code::day!(2022, opt.day, opt.puzzle, day24), 25 => advent_of_code::day!(2022, opt.day, opt.puzzle, day25), diff --git a/src/grid.rs b/src/grid.rs index d988ec6..040b92b 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -76,6 +76,34 @@ impl std::ops::Sub for usize { } } +impl std::ops::Mul for Row { + type Output = Self; + fn mul(self, other: usize) -> Self::Output { + Self(self.0 * other) + } +} + +impl std::ops::Mul for usize { + type Output = Row; + fn mul(self, other: Row) -> Self::Output { + Row(self * other.0) + } +} + +impl std::ops::Mul for Col { + type Output = Self; + fn mul(self, other: usize) -> Self::Output { + Self(self.0 * other) + } +} + +impl std::ops::Mul for usize { + type Output = Col; + fn mul(self, other: Col) -> Self::Output { + Col(self * other.0) + } +} + impl std::ops::Rem for Row { type Output = Self; fn rem(self, other: usize) -> Self::Output { @@ -183,11 +211,11 @@ impl std::ops::Sub for isize { } #[derive(Default, Clone, Debug, Eq, PartialEq, Hash)] -pub struct GridRow { +pub struct GridRow { cells: Vec, } -impl GridRow { +impl GridRow { pub fn iter(&self) -> impl Iterator + Clone { self.cells.iter() } @@ -197,8 +225,8 @@ impl GridRow { } } -impl - std::ops::Index for GridRow +impl std::ops::Index + for GridRow { type Output = T; fn index(&self, col: Col) -> &Self::Output { @@ -206,29 +234,26 @@ impl } } -impl - std::ops::IndexMut for GridRow +impl std::ops::IndexMut + for GridRow { fn index_mut(&mut self, col: Col) -> &mut Self::Output { &mut self.cells[col.0] } } -#[derive(Default, Clone, Debug, Eq, PartialEq, Hash)] -pub struct Grid { +#[derive(Clone, Debug, Eq, PartialEq, Hash)] +pub struct Grid { rows: Vec>, } -impl Grid { - pub fn grow(&mut self, rows: Row, cols: Col) { - self.rows - .resize_with(rows.0.max(self.rows.len()), GridRow::default); - for row in &mut self.rows { - row.cells - .resize_with(cols.0.max(row.cells.len()), T::default); - } +impl Default for Grid { + fn default() -> Self { + Self { rows: vec![] } } +} +impl Grid { pub fn unshift_rows(&mut self, count: usize) { self.rows = self.rows.split_off(count); } @@ -299,14 +324,19 @@ impl Grid { } } -impl< - T: Default - + Clone - + Eq - + PartialEq - + std::hash::Hash - + std::fmt::Display, - > Grid +impl Grid { + pub fn grow(&mut self, rows: Row, cols: Col) { + self.rows + .resize_with(rows.0.max(self.rows.len()), GridRow::default); + for row in &mut self.rows { + row.cells + .resize_with(cols.0.max(row.cells.len()), T::default); + } + } +} + +impl + Grid { pub fn display_packed char>( &self, @@ -316,14 +346,8 @@ impl< } } -impl< - T: Default - + Clone - + Eq - + PartialEq - + std::hash::Hash - + std::fmt::Display, - > std::fmt::Display for Grid +impl + std::fmt::Display for Grid { fn fmt( &self, @@ -339,8 +363,8 @@ impl< } } -impl - std::ops::Index for Grid +impl std::ops::Index + for Grid { type Output = GridRow; fn index(&self, row: Row) -> &Self::Output { @@ -348,8 +372,8 @@ impl } } -impl - std::ops::IndexMut for Grid +impl std::ops::IndexMut + for Grid { fn index_mut(&mut self, row: Row) -> &mut Self::Output { &mut self.rows[row.0] @@ -363,9 +387,19 @@ impl where I: IntoIterator>, { - Self { + let mut self_ = Self { rows: iter.into_iter().map(|v| GridRow { cells: v }).collect(), - } + }; + let nrows = self_.rows.len(); + let ncols = self_ + .rows + .iter() + .map(|row| row.cells.len()) + .max() + .unwrap_or(0); + self_.grow(Row(nrows), Col(ncols)); + + self_ } } @@ -387,7 +421,7 @@ impl pub struct DisplayPacked< 'a, - T: Default + Clone + Eq + PartialEq + std::hash::Hash + std::fmt::Display, + T: Clone + Eq + PartialEq + std::hash::Hash + std::fmt::Display, F: Fn(&'a T) -> char, >(&'a Grid, F); diff --git a/src/parse.rs b/src/parse.rs index 6969e84..0434ec0 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -109,7 +109,7 @@ pub fn digit_grid(lines: impl Iterator) -> Grid { pub fn grid(lines: impl Iterator, mut f: F) -> Grid where F: FnMut(u8, Row, Col) -> T, - T: Clone + Default + Eq + PartialEq + std::hash::Hash, + T: Default + Clone + Eq + PartialEq + std::hash::Hash, { lines .enumerate() -- cgit v1.2.3-54-g00ecf