From 7f811ce999dbbb14dbe7181332d2ce7d04a047f4 Mon Sep 17 00:00:00 2001 From: Lucy Date: Wed, 4 Dec 2024 08:59:07 +0100 Subject: [PATCH] feat: day 4 --- inputs/day04/example.txt | 10 +++ src/day04.rs | 130 +++++++++++++++++++++++++++++++++++++++ src/main.rs | 2 + 3 files changed, 142 insertions(+) create mode 100644 inputs/day04/example.txt create mode 100644 src/day04.rs diff --git a/inputs/day04/example.txt b/inputs/day04/example.txt new file mode 100644 index 0000000..c41c5ea --- /dev/null +++ b/inputs/day04/example.txt @@ -0,0 +1,10 @@ +MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX \ No newline at end of file diff --git a/src/day04.rs b/src/day04.rs new file mode 100644 index 0000000..bd70fa9 --- /dev/null +++ b/src/day04.rs @@ -0,0 +1,130 @@ +pub fn pt1(input: &str) -> usize { + let lines = input + .lines() + .map(|l| l.chars().collect::>()) + .collect::>(); + let mut count = 0; + for (i, line) in lines.iter().enumerate() { + for (j, c) in line.iter().enumerate() { + if *c == 'X' { + if j >= 3 + && line.get(j.saturating_sub(1)) == Some(&'M') + && line.get(j.saturating_sub(2)) == Some(&'A') + && line.get(j.saturating_sub(3)) == Some(&'S') + { + count += 1; + } + if j + 3 <= line.len() + && line.get(j + 1) == Some(&'M') + && line.get(j + 2) == Some(&'A') + && line.get(j + 3) == Some(&'S') + { + count += 1; + } + if i >= 3 + && lines.get(i.saturating_sub(1)).and_then(|l| l.get(j)) == Some(&'M') + && lines.get(i.saturating_sub(2)).and_then(|l| l.get(j)) == Some(&'A') + && lines.get(i.saturating_sub(3)).and_then(|l| l.get(j)) == Some(&'S') + { + count += 1; + } + if i + 3 <= lines.len() + && lines.get(i + 1).and_then(|l| l.get(j)) == Some(&'M') + && lines.get(i + 2).and_then(|l| l.get(j)) == Some(&'A') + && lines.get(i + 3).and_then(|l| l.get(j)) == Some(&'S') + { + count += 1; + } + if i >= 3 + && j >= 3 + && lines + .get(i.saturating_sub(1)) + .and_then(|l| l.get(j.saturating_sub(1))) + == Some(&'M') + && lines + .get(i.saturating_sub(2)) + .and_then(|l| l.get(j.saturating_sub(2))) + == Some(&'A') + && lines + .get(i.saturating_sub(3)) + .and_then(|l| l.get(j.saturating_sub(3))) + == Some(&'S') + { + count += 1; + } + if i >= 3 + && j + 3 <= line.len() + && lines.get(i.saturating_sub(1)).and_then(|l| l.get(j + 1)) == Some(&'M') + && lines.get(i.saturating_sub(2)).and_then(|l| l.get(j + 2)) == Some(&'A') + && lines.get(i.saturating_sub(3)).and_then(|l| l.get(j + 3)) == Some(&'S') + { + count += 1; + } + if j >= 3 + && i + 3 <= lines.len() + && lines.get(i + 1).and_then(|l| l.get(j.saturating_sub(1))) == Some(&'M') + && lines.get(i + 2).and_then(|l| l.get(j.saturating_sub(2))) == Some(&'A') + && lines.get(i + 3).and_then(|l| l.get(j.saturating_sub(3))) == Some(&'S') + { + count += 1; + } + if j + 3 <= line.len() + && i + 3 <= lines.len() + && lines.get(i + 1).and_then(|l| l.get(j + 1)) == Some(&'M') + && lines.get(i + 2).and_then(|l| l.get(j + 2)) == Some(&'A') + && lines.get(i + 3).and_then(|l| l.get(j + 3)) == Some(&'S') + { + count += 1; + } + } + } + } + count +} + +pub fn pt2(input: &str) -> usize { + let lines = input + .lines() + .map(|l| l.chars().collect::>()) + .collect::>(); + let mut count = 0; + for (i, line) in lines.iter().enumerate() { + for (j, c) in line.iter().enumerate() { + if *c == 'A' && (j >= 1 && i >= 1 && j + 1 < line.len() && i + 1 < lines.len()) { + let top_left = lines.get(i - 1).and_then(|l| l.get(j - 1)); + let bottom_right = lines.get(i + 1).and_then(|l| l.get(j + 1)); + let bottom_left = lines.get(i + 1).and_then(|l| l.get(j - 1)); + let top_right = lines.get(i - 1).and_then(|l| l.get(j + 1)); + if ((top_left == Some(&'M') && bottom_right == Some(&'S')) + || (top_left == Some(&'S') && bottom_right == Some(&'M'))) + && ((bottom_left == Some(&'M') && top_right == Some(&'S')) + || (bottom_left == Some(&'S') && top_right == Some(&'M'))) + { + count += 1; + } + } + } + } + count +} + +#[cfg(test)] +mod tests { + use std::fs::read_to_string; + + use super::{pt1, pt2}; + + #[test] + pub fn test_pt1() { + let input = + read_to_string("./inputs/day04/example.txt").expect("Missing example.txt for day04"); + assert_eq!(pt1(&input), 18) + } + #[test] + pub fn test_pt2() { + let input = + read_to_string("./inputs/day04/example.txt").expect("Missing example_2.txt for day04"); + + assert_eq!(pt2(&input), 9) + } +} diff --git a/src/main.rs b/src/main.rs index c722a87..b89e736 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,12 +3,14 @@ use std::{fmt::Display, fs::read_to_string, time::Instant}; mod day01; mod day02; mod day03; +mod day04; fn main() { color_eyre::install().unwrap(); tracing_subscriber::fmt::init(); solve_day(1, day01::pt1, day01::pt2); solve_day(2, day02::pt1, day02::pt2); solve_day(3, day03::pt1, day03::pt2); + solve_day(4, day04::pt1, day04::pt2); } fn solve_day(day: u8, part_a: Fa, part_b: Fb)