]> aoc.elinar.fr Git - aoc_2024/commitdiff
Day04 - part 1
authoralex <>
Wed, 4 Dec 2024 08:47:21 +0000 (09:47 +0100)
committeralex <>
Wed, 4 Dec 2024 08:47:21 +0000 (09:47 +0100)
src/day04.rs [new file with mode: 0644]
src/main.rs

diff --git a/src/day04.rs b/src/day04.rs
new file mode 100644 (file)
index 0000000..c885a7a
--- /dev/null
@@ -0,0 +1,124 @@
+use std::error::Error;
+use std::path::Path;
+
+pub fn run(input: &str) -> Result<(), Box<dyn Error>> {
+    let res = run_part1(&input)?;
+    println!("{res}");
+
+    let res = run_part2(&input)?;
+    println!("{res}");
+
+    Ok(())
+}
+
+struct Puzzle {
+    map: Vec<Vec<char>>,
+    x_pos: Vec<(usize, usize)>,
+}
+
+impl Puzzle {
+    pub fn new(input: &str) -> Self {
+        let mut map: Vec<Vec<char>> = input.lines()
+            .map(|l| {
+                let s = ".".to_owned() + l + ".";
+                s.chars().collect()
+            })
+            .collect();
+        map.insert(0, vec!['.'; map[0].len()]);
+        map.push(vec!['.'; map[0].len()]);
+
+        // 'X' coordinates
+        let mut x_pos = Vec::<(usize, usize)>::new();
+        map.iter().enumerate()
+            .for_each(|(r, row)| {
+                row.iter().enumerate()
+                    .for_each(|(c, v)| {
+                        if *v == 'X' {
+                            x_pos.push((r, c));
+                        }
+                    });
+            });
+
+        Self {
+            map,
+            x_pos,
+        }
+    }
+}
+
+fn get_day() -> String {
+    let filename = file!();
+    Path::new(filename).file_stem().unwrap().to_str().unwrap().to_string()
+}
+
+fn run_part1(input: &str) -> Result<u32, Box<dyn Error>> {
+    println!("Running {} - part 1", get_day());
+
+    let dir = [
+        (-1,0), (-1,1), (0,1), (1,1),
+        (1,0), (1,-1), (0,-1), (-1,-1),
+    ];
+
+    let puzzle = Puzzle::new(input);
+
+    let mut res: u32 = 0;
+
+    // for each 'X' search for 'MAS' around and add 1 if found
+    for (row, col) in puzzle.x_pos {
+        for (dr, dc) in dir {
+            let (mut r, mut c) = (row, col);
+            for v in ['M', 'A', 'S'] {
+                r = ((r as i32) + dr) as usize;
+                c = ((c as i32) + dc) as usize;
+                if puzzle.map[r][c] != v {
+                    break;
+                }
+                else if puzzle.map[r][c] == 'S' {
+                    res += 1;
+                }
+            }
+        }
+    }
+
+    Ok(res)
+}
+
+fn run_part2(input: &str) -> Result<u32, Box<dyn Error>> {
+    println!("Running {} - part 2", get_day());
+
+    Ok(0)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    static TEXT_INPUT_1: &str = "\
+..X...
+.SAMX.
+.A..A.
+XMAS.S
+.X....";
+    static TEXT_INPUT_2: &str = "\
+MMMSXXMASM
+MSAMXMSMSA
+AMXSXMAAMM
+MSAMASMSMX
+XMASAMXAMM
+XXAMMXXAMA
+SMSMSASXSS
+SAXAMASAAA
+MAMMMXMMMM
+MXMXAXMASX";
+
+    #[test]
+    fn test_part1() {
+        assert_eq!(4, run_part1(TEXT_INPUT_1).unwrap());
+        assert_eq!(18, run_part1(TEXT_INPUT_2).unwrap());
+    }
+
+    #[test]
+    fn test_part2() {
+        assert_eq!(0, run_part2(TEXT_INPUT_2).unwrap());
+    }
+}
index fb8a3511fe4ff57a59cd909979489f4151fe931c..0a828f075d0ca1c716e35d928eca33dc47df45aa 100644 (file)
@@ -7,6 +7,7 @@ use std::io::Read;
 pub mod day01;
 pub mod day02;
 pub mod day03;
+pub mod day04;
 
 fn main() {
     let args: Vec<String> = env::args().collect();
@@ -32,6 +33,7 @@ fn run(day: &str, input_file: &str) -> Result<(), Box<dyn Error>> {
         "day01" => day01::run(&input)?,
         "day02" => day02::run(&input)?,
         "day03" => day03::run(&input)?,
+        "day04" => day04::run(&input)?,
         _ => return Err(format!("unknown or unimplemented day \"{day}\"").into()),
     }
     Ok(())