From b7bc7f15a34dde28ec8675a1ff3a991000a56495 Mon Sep 17 00:00:00 2001 From: Joe Ardent Date: Sun, 22 Dec 2024 16:09:08 -0800 Subject: [PATCH] day4, part1 --- Cargo.lock | 4 ++ Cargo.toml | 2 +- day04/Cargo.toml | 7 +++ day04/src/main.rs | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 day04/Cargo.toml create mode 100644 day04/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index c097eec..9f85b3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,10 @@ dependencies = [ "winnow", ] +[[package]] +name = "day04" +version = "0.1.0" + [[package]] name = "memchr" version = "2.7.4" diff --git a/Cargo.toml b/Cargo.toml index 6fcfcb6..95300e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "2" -members = ["day01", "day02", "day03"] +members = ["day01", "day02", "day03", "day04"] [workspace.dependencies] winnow = "0.6" diff --git a/day04/Cargo.toml b/day04/Cargo.toml new file mode 100644 index 0000000..f56af55 --- /dev/null +++ b/day04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "day04" +version = "0.1.0" +edition = "2024" + +[dependencies] + diff --git a/day04/src/main.rs b/day04/src/main.rs new file mode 100644 index 0000000..9fb009b --- /dev/null +++ b/day04/src/main.rs @@ -0,0 +1,129 @@ +static MAS: [char; 3] = ['M', 'A', 'S']; +static DIRS: [Dir; 8] = [ + Dir::N, + Dir::S, + Dir::E, + Dir::W, + Dir::NE, + Dir::NW, + Dir::SE, + Dir::SW, +]; + +fn main() { + let input = std::fs::read_to_string("input").unwrap(); + println!("{}", pt1(&input)); + println!("{}", pt2(&input)); +} + +fn pt1(input: &str) -> u32 { + let mut total = 0; + let board = Board::new(input); + + for (r, row) in board.rows.iter().enumerate() { + for (c, letter) in row.iter().enumerate() { + if letter == &'X' { + for &dir in DIRS.iter() { + if find_xmas(&board, (r, c), dir) { + total += 1; + } + } + } + } + } + + total +} + +fn find_xmas(board: &Board, loc: (usize, usize), dir: Dir) -> bool { + let (mut r, mut c) = loc; + for l in MAS { + if let Some(&nl) = board.next((r, c), dir) { + if nl != l { + return false; + } + (r, c) = dir.next((r, c)); + } else { + return false; + } + } + true +} + +fn pt2(_input: &str) -> u32 { + 0 +} + +struct Board { + rows: Vec>, +} + +impl Board { + fn new(input: &str) -> Self { + let rows = input.split('\n').map(|l| l.chars().collect()).collect(); + Board { rows } + } + + fn at(&self, loc: (usize, usize)) -> Option<&char> { + self.rows.get(loc.0).and_then(|r| r.get(loc.1)) + } + + fn next(&self, loc: (usize, usize), dir: Dir) -> Option<&char> { + let (nr, nc) = dir.next(loc); + self.at((nr, nc)) + } +} + +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum Dir { + N, + S, + E, + W, + NE, + NW, + SE, + SW, +} + +impl Dir { + fn next(&self, loc: (usize, usize)) -> (usize, usize) { + let (r, c) = loc; + let (nr, nc) = match self { + Dir::N => (r.wrapping_sub(1), c), + Dir::S => (r + 1, c), + Dir::E => (r, c + 1), + Dir::W => (r, c.wrapping_sub(1)), + Dir::NE => (r.wrapping_sub(1), c + 1), + Dir::NW => (r.wrapping_sub(1), c.wrapping_sub(1)), + Dir::SE => (r + 1, c + 1), + Dir::SW => (r + 1, c.wrapping_sub(1)), + }; + + (nr, nc) + } +} + +#[cfg(test)] +mod test { + use super::*; + + static I1: &str = "MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX"; + + #[test] + fn p1() { + assert_eq!(18, pt1(I1)); + } + + #[test] + fn p2() {} +}