use std::{ error::Error, fs, ops::{Add, Mul}, }; #[derive(Debug, PartialEq, Eq, Copy, Clone)] struct Point { pub x: i64, pub y: i64, } impl Point { fn new(x: i64, y: i64) -> Self { Self { x, y } } } impl Mul for Point { type Output = Self; fn mul(self, rhs: i64) -> Self::Output { Point { x: self.x * rhs, y: self.y * rhs, } } } impl Add for Point { type Output = Self; fn add(self, rhs: Self) -> Self::Output { Point { x: self.x + rhs.x, y: self.y + rhs.y, } } } #[derive(Debug, PartialEq, Eq, Copy, Clone)] enum Dir { North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest, } impl Dir { const DIRS: [Dir; 8] = [ Dir::North, Dir::NorthEast, Dir::East, Dir::SouthEast, Dir::South, Dir::SouthWest, Dir::West, Dir::NorthWest, ]; fn grid_offset(self) -> Point { match self { Dir::North => Point::new(0, 1), Dir::NorthEast => Point::new(1, 1), Dir::East => Point::new(1, 0), Dir::SouthEast => Point::new(1, -1), Dir::South => Point::new(0, -1), Dir::SouthWest => Point::new(-1, -1), Dir::West => Point::new(-1, 0), Dir::NorthWest => Point::new(-1, 1), } } } fn index_at(board: &[&[u8]], point: Point) -> Option { Some( *board .get(usize::try_from(point.y).ok()?)? .get(usize::try_from(point.x).ok()?)?, ) } fn main() -> Result<(), Box> { let mut xmas_count = 0; let mut x_mas_count = 0; let to_find = b"XMAS"; let input = fs::read("input/4")?; let input: Box<[&[u8]]> = input.trim_ascii_end().split(|e| *e == b'\n').collect(); for y in 0..input.len() { for x in 0..input[y].len() { let p = Point::new(x as i64, y as i64); for d in Dir::DIRS { if to_find .iter() .copied() .enumerate() .all(|c| index_at(&input, p + d.grid_offset() * c.0 as i64) == Some(c.1)) { xmas_count += 1; } } if input[y][x] == b'A' { let check = |a, b| { (a == Some(b'M') && b == Some(b'S')) || (a == Some(b'S') && b == Some(b'M')) }; if check( index_at(&input, p + Dir::NorthEast.grid_offset()), index_at(&input, p + Dir::SouthWest.grid_offset()), ) && check( index_at(&input, p + Dir::NorthWest.grid_offset()), index_at(&input, p + Dir::SouthEast.grid_offset()), ) { x_mas_count += 1; } } } } println!("{xmas_count}\n{x_mas_count}"); Ok(()) }