summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2024-12-04 16:22:32 +0000
committerTomasz Kramkowski <tomasz@kramkow.ski>2024-12-04 16:22:32 +0000
commit6543c06d5ccd34363d5e44eae6f565756fd1de68 (patch)
treedbed66830b4f02aa01d84e6f1b9cbd761e4f0121
parent91c27347645fa5550bcc4dc40150c2c097ca7057 (diff)
downloadaoc2024-6543c06d5ccd34363d5e44eae6f565756fd1de68.tar.gz
aoc2024-6543c06d5ccd34363d5e44eae6f565756fd1de68.tar.xz
aoc2024-6543c06d5ccd34363d5e44eae6f565756fd1de68.zip
Day 4
-rw-r--r--src/bin/4.rs121
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(())
+}