Solution for 2021 day 9 part 1
[?]
Dec 12, 2021, 10:24 PM
E5UDZGDTQH4K24S5DGGXSH3DVDOV745VWKNIEXE6JGSEUSDU36CACDependencies
Change contents
- file addition: day9.rs[4.16]
fn main() {use std::io::BufRead;let mut grid: Grid<u8> = Grid::with_outside(u8::MAX);let filename = std::env::args().nth(1).expect("Expected filename");let file = std::io::BufReader::new(std::fs::File::open(<String as AsRef<std::path::Path>>::as_ref(&filename,)).unwrap(),);for (y, line) in file.lines().enumerate() {for (x, c) in line.unwrap().chars().enumerate() {grid[(x, y)] = c.to_digit(10).unwrap_or(u8::MAX as u32) as u8;}}println!("risk level: {}",grid.minima().map(|p| grid[p] as u16 + 1).sum::<u16>());}#[derive(Debug)]struct Grid<T> {inner: Vec<T>,outside: T,width: usize,}impl<T> Grid<T> {fn with_outside(outside: T) -> Self {Self {inner: Vec::new(),outside,width: 0,}}fn height(&self) -> usize {self.inner.len() / self.width.max(1)}fn width(&self) -> usize {self.width}fn neighbours(&self, point: (usize, usize)) -> Neighbours {Neighbours::new(point, (self.width(), self.height()))}fn points(&self) -> GridPoints {GridPoints::new(self.width, self.height())}}impl<T: Ord> Grid<T> {fn minima(&self) -> impl Iterator<Item = (usize, usize)> + '_ {self.points().filter(move |p| {let c = &self[*p];let mut r = false;for n in self.neighbours(*p).map(|n| &self[n]) {match c.cmp(n) {std::cmp::Ordering::Less => {r = true;}std::cmp::Ordering::Equal => {}std::cmp::Ordering::Greater => {r = false;break;}}}r})}}impl<T> std::ops::Index<(usize, usize)> for Grid<T> {type Output = T;fn index(&self, (x, y): (usize, usize)) -> &Self::Output {if x >= self.width {&self.outside} else {let i = y * self.width + x;self.inner.get(i).unwrap_or(&self.outside)}}}impl<T: Clone> std::ops::IndexMut<(usize, usize)> for Grid<T> {fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {let new_width = self.width().max(x + 1);let new_height = self.height().max(y + 1);if new_width > self.width() || new_height > self.height() {self.inner = (0..new_width * new_height).map(|i| self[(i % new_width, i / new_width)].clone()).collect();self.width = new_width;}self.inner.index_mut(y * self.width + x)}}struct GridPoints {width: usize,height: usize,x: usize,y: usize,}impl GridPoints {fn new(width: usize, height: usize) -> Self {Self {width,height,x: 0,y: 0,}}}impl Iterator for GridPoints {type Item = (usize, usize);fn next(&mut self) -> Option<Self::Item> {let x = self.x;let y = self.y;if y < self.height {let x_n = x + 1;if x_n >= self.width {self.x = 0;self.y = y + 1;} else {self.x = x_n;}Some((x, y))} else {None}}fn size_hint(&self) -> (usize, Option<usize>) {let n = self.width * (self.height - self.y) - self.x;(n, Some(n))}}struct Neighbours {centre: (usize, usize),dimensions: (usize, usize),i: u8,}impl Neighbours {fn new(centre: (usize, usize), dimensions: (usize, usize)) -> Self {Self {centre,dimensions,i: 0,}}}impl Iterator for Neighbours {type Item = (usize, usize);fn next(&mut self) -> Option<Self::Item> {match self.i {0 => {self.i = 1;if self.centre.1 > 0 {Some((self.centre.0, self.centre.1 - 1))} else {self.next()}}1 => {self.i = 2;let x = self.centre.0 + 1;if x < self.dimensions.0 {Some((x, self.centre.1))} else {self.next()}}2 => {self.i = 3;let y = self.centre.1 + 1;if y < self.dimensions.1 {Some((self.centre.0, self.centre.1 + 1))} else {self.next()}}3 => {self.i = 4;if self.centre.0 > 0 {Some((self.centre.0 - 1, self.centre.1))} else {self.next()}}_ => None,}}fn size_hint(&self) -> (usize, Option<usize>) {(0, Some((4 - self.i).into()))}} - edit in 2021/Cargo.toml at line 33[2.1171]
[[bin]]name = "day9"path = "day9.rs"