Advent of Code day 9 solution

This code gives correct answer for example input but not for user input. (Gives way more answer) I would like to get some hints or answers about my code. Thanks my fellow rustaceans!

fn main() {

    let a =  "2199943210
3987894921
9856789892
8767896789
9899965678".to_string();

    let a: Vec<Vec<u32>> = a.lines().map(|s|s.trim().chars().map(|c|c.to_digit(10).unwrap()).collect::<Vec<u32>>()).collect();

    let LIMIT_ROW: usize = a.len();
    let LIMIT_COLUMN: usize = a[0].len();

    let mut ans: Vec<u32> = Vec::new();

    for (row_index ,row) in a.iter().enumerate() {

        for (col_index,col) in row.iter().enumerate() {

            let mut sides: Vec<u32> = Vec::new();

            let (left_side,right_side) = ((col_index as i32 -1),(col_index as i32 +1));

            let (up_side,down_side) = ((row_index as i32-1) ,(row_index as i32+1));

            if left_side >= 0  as i32 {
                sides.push(a[row_index][left_side as usize])
            }

            if right_side < LIMIT_COLUMN as i32 {
                sides.push(a[row_index][right_side as usize])
            }

            if up_side >= 0 {
                sides.push(a[up_side as usize][col_index])
            }

            if down_side < LIMIT_ROW as i32 {
                sides.push(a[down_side as usize][col_index])
            }
            sides.push(*col);

                match sides.iter().min() {
                    Some(min) if *min == *col => {

                        ans.push(*col+1);
                    },
                    _ => {}
                }

            sides.clear()

        }

    }
    
    println!("ans: {}",ans.iter().sum::<u32>());

}

It's not immediately apparent what this code is trying to achieve because everything is in one big function and you've got lots of indexing or integer casts.

Are you able to split it up into smaller functions which implement different parts of your algorithm? You might also want to extract out higher level concepts like a 2D Matrix and a Coordinate.

Thinking in terms of higher level concepts makes it a lot easier to reason about the problem, and when it is easier to reason about a problem. silly bugs often become obvious or outright impossible to occur by design.

1 Like

Given that description, the first place I would look is in the code that collects user input, which as I understand it, you have not included here yet. In particular, I would suggest examining the Vec<Vec<u32>> that is produced if you input the example numbers, and seeing if it is at all different from the vector produced by the example input string.

Since the problem seems related to input only, I think moving non-input/output code away from other code may make it easier to spot input/output issues.

In this case, putting the calculation, (going from a to ans) into a separate function seems like a reasonable approach, similar to what @Michael-F-Bryan suggested.

You could print some information (e.g. coordinates, values of cell and its neighbors) when an answer is found, and check that to see what is wrong.

I didn't do AoC, so I don't know the answer, and like most similar problem exercises, the description lacks accuracy:

Your first goal is to find the low points - the locations that are lower than any of its adjacent locations.
[...]
All other locations on the heightmap have some lower adjacent location, and so are not low points.

Are cells surrounded by other cells of the same value low points or not? Unclear. The first sentence implies low points must be strictly lower, the second sentence implies the opposite (to me). The example input has no such use case to check against.

So this is just a guess, but does it fix the problem?

-            sides.push(*col);
+            // Just don't store *col

             match sides.iter().min() {
-                Some(min) if *min == *col => {
+                // Only consider this a low point if strictly lower
+                Some(min) if *min > *col => {
                     ans.push(*col + 1);
                 }
                 _ => {}
             }