]> localhost Git - adventofcode2024.git/commitdiff
Tidy up day 4
authorJack Kinsey <j.jameskinsey@gmail.com>
Thu, 5 Dec 2024 03:48:05 +0000 (22:48 -0500)
committerJack Kinsey <j.jameskinsey@gmail.com>
Thu, 5 Dec 2024 03:48:05 +0000 (22:48 -0500)
src/day04.rs

index 96e8f7b4913f22a938d93e3f95f03acea152ca3a..1e47365eabe8610751c7c19aae17a27c0c694f81 100644 (file)
@@ -28,18 +28,13 @@ fn parse(input: &str) -> Vec<Vec<Char>> {
         .collect()
 }
 
-fn find_chars(chars: &[Vec<Char>], char: Char) -> Vec<(i32, i32)> {
-    chars
-        .iter()
-        .enumerate()
-        .flat_map(|(i, v)| {
-            v.iter()
-                .enumerate()
-                .filter(|(_, &c)| c == char)
-                .map(move |(j, _)| (i, j))
-                .map(|(i, j)| (i.try_into().unwrap(), j.try_into().unwrap()))
-        })
-        .collect()
+fn find_chars(chars: &[Vec<Char>], char: Char) -> impl Iterator<Item = (i32, i32)> + use<'_> {
+    chars.iter().zip(0..).flat_map(move |(v, i)| {
+        v.iter()
+            .zip(0..)
+            .filter(move |(&c, _)| c == char)
+            .map(move |(_, j)| (i, j))
+    })
 }
 
 #[rustfmt::skip]
@@ -49,60 +44,47 @@ const DIRS: [(i32, i32); 8] = [
      (1, -1),  (1, 0),  (1, 1),
 ];
 
-fn make_dirs((i, j): (i32, i32), n: i32) -> Vec<[(usize, usize); 4]> {
+fn make_dirs<'a>(
+    (i, j): (i32, i32),
+    n: i32,
+) -> impl Iterator<Item = [(usize, usize); 4]> + use<'a> {
     DIRS.iter()
-        .map(|dir| {
+        .map(move |dir| {
             [dir]
                 .iter()
                 .cycle()
                 .take(4)
-                .enumerate()
-                .map(|(k, dij)| (std::convert::TryInto::<i32>::try_into(k).unwrap(), dij))
-                .map(|(k, (di, dj))| (i + k * di, j + k * dj))
+                .zip(0..) // to avoid type issues
+                .map(|((di, dj), k)| (i + k * di, j + k * dj))
                 .collect::<Vec<_>>()
-                .try_into()
-                .unwrap()
         })
-        .filter(|ds: &[(i32, i32); 4]| {
+        .filter(move |ds| {
             ds.iter()
-                .all(|(ii, jj)| *ii >= 0 && *jj >= 0 && *ii < n && *jj < n)
+                .all(|&(ii, jj)| ii >= 0 && jj >= 0 && ii < n && jj < n)
         })
-        .map(|ds: [(i32, i32); 4]| {
+        .map(|ds| {
             ds.iter()
-                .map(|(ii, jj)| {
-                    (
-                        TryInto::<usize>::try_into(*ii).unwrap(),
-                        TryInto::<usize>::try_into(*jj).unwrap(),
-                    )
-                })
+                .map(|&(ii, jj)| (ii.try_into().unwrap(), jj.try_into().unwrap()))
                 .collect::<Vec<_>>()
                 .try_into()
                 .unwrap()
         })
-        .collect()
 }
 
 #[rustfmt::skip]
 const XDIRS: [(i32, i32); 4] = [
-    (-1, -1),          (-1, 1),
-              /* ctr */        
-     (1, -1),           (1, 1),
+    (-1, -1), (-1, 1),
+     (1, -1),  (1, 1),
 ];
 
 fn make_xdirs((i, j): (i32, i32), n: i32) -> Option<[(usize, usize); 4]> {
-    if i == 0 || i == n - 1 || j == 0 || j == n - 1 {
+    if i == 0 || i >= n - 1 || j == 0 || j >= n - 1 {
         None
     } else {
         Some(
             XDIRS
                 .iter()
-                .map(|&(di, dj)| (i + di, j + dj))
-                .map(|(ii, jj)| {
-                    (
-                        TryInto::<usize>::try_into(ii).unwrap(),
-                        TryInto::<usize>::try_into(jj).unwrap(),
-                    )
-                })
+                .map(|&(di, dj)| ((i + di).try_into().unwrap(), (j + dj).try_into().unwrap()))
                 .collect::<Vec<_>>()
                 .try_into()
                 .unwrap(),
@@ -112,21 +94,18 @@ fn make_xdirs((i, j): (i32, i32), n: i32) -> Option<[(usize, usize); 4]> {
 
 fn check_x_for_xmas(chars: &[Vec<Char>], coords: (i32, i32)) -> usize {
     make_dirs(coords, chars.len().try_into().unwrap())
-        .iter()
-        .map(|ijs| {
+        .filter(|ijs| {
             matches!(
-                ijs.iter().map(|(i, j)| chars[*i][*j]).collect::<Vec<_>>()[..],
+                ijs.iter().map(|&(i, j)| chars[i][j]).collect::<Vec<_>>()[..],
                 [Char::X, Char::M, Char::A, Char::S]
             )
         })
-        .filter(|&x| x)
         .count()
 }
 
 fn check_xs_for_xmas(chars: &[Vec<Char>]) -> usize {
     find_chars(chars, Char::X)
-        .iter()
-        .map(|&coords| check_x_for_xmas(chars, coords))
+        .map(|coords| check_x_for_xmas(chars, coords))
         .sum()
 }
 
@@ -138,23 +117,18 @@ const XPATTERNS: [[Char; 4]; 4] = [
 ];
 
 fn check_a_for_xmas(chars: &[Vec<Char>], coords: (i32, i32)) -> usize {
-    if let Some(x) = make_xdirs(coords, chars.len().try_into().unwrap()) {
-        let xc: [Char; 4] = x
-            .iter()
-            .map(|(i, j): &(usize, usize)| chars[*i][*j])
-            .collect::<Vec<_>>()
-            .try_into()
-            .unwrap();
-        XPATTERNS.iter().filter(|&&p| p == xc).count()
-    } else {
-        0
+    match make_xdirs(coords, chars.len().try_into().unwrap()) {
+        Some(x) => {
+            let cs = &x.iter().map(|&(i, j)| chars[i][j]).collect::<Vec<_>>()[..];
+            XPATTERNS.iter().filter(|&p| p == cs).count()
+        }
+        None => 0,
     }
 }
 
 fn check_as_for_xmas(chars: &[Vec<Char>]) -> usize {
     find_chars(chars, Char::A)
-        .iter()
-        .map(|&coords| check_a_for_xmas(chars, coords))
+        .map(|coords| check_a_for_xmas(chars, coords))
         .sum()
 }
 
@@ -200,8 +174,8 @@ mod test {
                 [ Char::S, Char::M, Char::S, Char::M, Char::S, Char::A, Char::S, Char::X, Char::S, Char::S ],
                 [ Char::S, Char::A, Char::X, Char::A, Char::M, Char::A, Char::S, Char::A, Char::A, Char::A ],
                 [ Char::M, Char::A, Char::M, Char::M, Char::M, Char::X, Char::M, Char::M, Char::M, Char::M ],
-                [ Char::M, Char::X, Char::M, Char::X, Char::A, Char::X, Char::M, Char::A, Char::S, Char::X ]
-            ]
+                [ Char::M, Char::X, Char::M, Char::X, Char::A, Char::X, Char::M, Char::A, Char::S, Char::X ],
+            ],
         )
     }
 
@@ -209,7 +183,7 @@ mod test {
     #[test]
     fn test_find_xs() {
         assert_eq!(
-            find_chars(&parse(INPUT_STR), Char::X),
+            find_chars(&parse(INPUT_STR), Char::X).collect::<Vec<_>>(),
             [
                 (0, 4), (0, 5),
                 (1, 4),
@@ -220,22 +194,22 @@ mod test {
                 (6, 7),
                 (7, 2),
                 (8, 5),
-                (9, 1), (9, 3), (9, 5), (9, 9)
-            ]
+                (9, 1), (9, 3), (9, 5), (9, 9),
+            ],
         )
     }
 
     #[test]
     fn test_make_dirs() {
         assert_eq!(
-            make_dirs((0, 4), 10),
+            make_dirs((0, 4), 10).collect::<Vec<_>>(),
             [
                 [(0, 4), (0, 3), (0, 2), (0, 1)],
                 [(0, 4), (0, 5), (0, 6), (0, 7)],
                 [(0, 4), (1, 3), (2, 2), (3, 1)],
                 [(0, 4), (1, 4), (2, 4), (3, 4)],
-                [(0, 4), (1, 5), (2, 6), (3, 7)]
-            ]
+                [(0, 4), (1, 5), (2, 6), (3, 7)],
+            ],
         )
     }
 
@@ -249,7 +223,7 @@ mod test {
         assert_eq!(make_xdirs((0, 4), 10), None);
         assert_eq!(
             make_xdirs((1, 1), 10),
-            Some([(0, 0), (0, 2), (2, 0), (2, 2)])
+            Some([(0, 0), (0, 2), (2, 0), (2, 2)]),
         );
     }