From 8f51f3914effb85f9928b7d7b2349e07a104baf5 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sat, 07 Dec 2024 17:14:56 +0000 Subject: [PATCH] Add 2024 day 4 --- Cargo.toml | 4 ++++ README | 4 ++-- 2024/01.rs | 1 + 2024/04.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 246299a..173c6d7 100644 --- a/Cargo.toml +++ a/Cargo.toml @@ -30,6 +30,10 @@ name = "aoc2024-01" path = "2024/01.rs" +[[bin]] +name = "aoc2024-04" +path = "2024/04.rs" + [profile.release] overflow-checks = true diff --git a/README b/README index 5d29f89..17ee834 100644 --- a/README +++ a/README @@ -17,8 +17,8 @@ | 1 | Rust | | 1 | Haskell | | 1 | Fortran | | 2 | OCaml | | 2 | Haskell | | 2 | Nix | | 3 | Perl | | 3 | Haskell | | 3 | Clojure | -+---------------------+ | 4 | Haskell | | 4 | Jsonnet | - | 5 | Rust | | 5 | HCL/TF | +| 4 | Rust | | 4 | Haskell | | 4 | Jsonnet | ++---------------------+ | 5 | Rust | | 5 | HCL/TF | | 6 | Haskell | | 6 | Apache2 | | 7 | Haskell | +---------------------+ | 8 | Haskell | diff --git a/2024/01.rs b/2024/01.rs index 36325c2..e1bd931 100644 --- a/2024/01.rs +++ a/2024/01.rs @@ -1,4 +1,5 @@ #![feature(binary_heap_into_iter_sorted)] +#![allow(clippy::cast_possible_truncation)] use std::{cmp::Reverse, collections::BinaryHeap, io::Read}; use itertools::Itertools; diff --git a/2024/04.rs b/2024/04.rs new file mode 100644 index 0000000..2509859 100644 --- /dev/null +++ a/2024/04.rs @@ -1,0 +1,109 @@ +#![allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] + +use std::io::Read; + +use itertools::Itertools; + +fn main() { + let mut input = String::new(); + std::io::stdin().read_to_string(&mut input).unwrap(); + let input = input.trim(); + + let rows = input.lines().count(); + let cols = input.split_once('\n').unwrap().0.len(); + + let input = input.replace('\n', ""); + + part1(&input, rows, cols); + part2(&input, cols); +} + +fn part1(input: &str, rows: usize, cols: usize) { + const VARIANTS: &[[(isize, isize); 3]] = &[ + // forward + [(1, 0), (2, 0), (3, 0)], + // backwards + [(-1, 0), (-2, 0), (-3, 0)], + // downwards + [(0, 1), (0, 2), (0, 3)], + // upwards + [(0, -1), (0, -2), (0, -3)], + // diag up left + [(-1, -1), (-2, -2), (-3, -3)], + // diag up right + [(1, -1), (2, -2), (3, -3)], + // diag down right + [(1, 1), (2, 2), (3, 3)], + // diag down left + [(-1, 1), (-2, 2), (-3, 3)], + ]; + + let char_at_pos = |n| &input[n..=n]; + let mut found = 0; + + let indicies = input + .char_indices() + .filter(|(_, c)| *c == 'X') + .collect_vec(); + + for (pos, _) in indicies { + let curr_char_row = pos / cols; + + let get_at_offset = |&(x, y): &(isize, isize)| { + char_at_pos((pos as isize + (cols as isize * y) + x) as usize) + }; + + for [v1, v2, v3] in VARIANTS { + let (max_x, max_y) = v3; + + // if max_x will overflow the row, or if the max_y will take us outside of the grid, + // skip + if (pos as isize + max_x) / cols as isize != curr_char_row as isize + || curr_char_row as isize + max_y < 0 + || curr_char_row as isize + max_y >= rows as isize + { + continue; + } + + if get_at_offset(v1) == "M" && get_at_offset(v2) == "A" && get_at_offset(v3) == "S" { + found += 1; + } + } + } + + eprintln!("{found}"); +} + +fn part2(input: &str, cols: usize) { + let char_at_pos = |n| &input[n..=n]; + let mut found = 0; + + let indicies = input + .char_indices() + .filter(|(_, c)| *c == 'A') + .collect_vec(); + + for (pos, _) in indicies { + let get_at_offset = + |(x, y): (isize, isize)| char_at_pos((pos as isize + (cols as isize * y) + x) as usize); + + if pos < cols || pos % cols < 1 || pos + cols > input.len() { + continue; + } + + let top_left = get_at_offset((-1, -1)); + let top_right = get_at_offset((1, -1)); + let bottom_left = get_at_offset((-1, 1)); + let bottom_right = get_at_offset((1, 1)); + + match (top_left, top_right, bottom_left, bottom_right) { + ("M", "S", "M", "S") + | ("S", "M", "S", "M") + | ("M", "M", "S", "S") + | ("S", "S", "M", "M") => found += 1, + _ => {} + } + } + + eprintln!("{found}"); +} -- rgit 0.1.5