diff options
author | Tomasz Kramkowski <tomasz@kramkow.ski> | 2024-12-04 16:22:32 +0000 |
---|---|---|
committer | Tomasz Kramkowski <tomasz@kramkow.ski> | 2024-12-04 16:22:32 +0000 |
commit | 6543c06d5ccd34363d5e44eae6f565756fd1de68 (patch) | |
tree | dbed66830b4f02aa01d84e6f1b9cbd761e4f0121 | |
parent | 91c27347645fa5550bcc4dc40150c2c097ca7057 (diff) | |
download | aoc2024-6543c06d5ccd34363d5e44eae6f565756fd1de68.tar.gz aoc2024-6543c06d5ccd34363d5e44eae6f565756fd1de68.tar.xz aoc2024-6543c06d5ccd34363d5e44eae6f565756fd1de68.zip |
Day 4
-rw-r--r-- | src/bin/4.rs | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/bin/4.rs b/src/bin/4.rs new file mode 100644 index 0000000..6fddcd6 --- /dev/null +++ b/src/bin/4.rs @@ -0,0 +1,121 @@ +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<i64> for Point { + type Output = Self; + fn mul(self, rhs: i64) -> Self::Output { + Point { + x: self.x * rhs, + y: self.y * rhs, + } + } +} + +impl Add<Point> 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<u8> { + Some( + *board + .get(usize::try_from(point.y).ok()?)? + .get(usize::try_from(point.x).ok()?)?, + ) +} + +fn main() -> Result<(), Box<dyn Error>> { + 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(()) +} |