fn basin_size_search(map: &Vec2d<u8>,
                     basin: &mut HashMap<(usize, usize), usize>,
                     prev_point: (usize, usize),
                     point: (usize, usize),
                     verbose: bool,
                     ) -> usize {
    // Stop at '9' or out of bounds.
    if map.at(point).map_or(true, |h| *h == 9) {
        if verbose { println!("({:2}, {:2}) basin bounds", point.0, point.1); }
        0
    } else {
        // We might already have the sum from this point.
        if let Some(size) = basin.get(&point) {
            if verbose {
                println!(
                    "({:2}, {:2}) already know size from here = {}",
                    point.0, point.1, *size
                );
            }
            0
        } else {
            // Insert a dummy size before we recurse to implement a 'visited' check.
            basin.insert(point, usize::MAX);
            if verbose {
                println!("({:2}, {:2}) looking for basin size...", point.0, point.1);
            }
            // Visit the basin in every direction except the direction we just came from.
            let size = 1 + if up(point) != prev_point {
                basin_size_search(map, basin, point, up(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            + if left(point) != prev_point {
                basin_size_search(map, basin, point, left(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            + if right(point) != prev_point {
                basin_size_search(map, basin, point, right(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            + if down(point) != prev_point {
                basin_size_search(map, basin, point, down(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            ;
            basin.insert(point, size);
            if verbose {
                println!("({:2}, {:2}) found basin size {}", point.0, point.1, size);
            }
            size
        }
    }
}
// Love recursion, but this is awful for stack size. TODO flatten this into a smarter loop.
Love recursion, but this is awful for stack size. TODO flatten this into a smarter loop.
Love recursion but this is awful for stack size . TODO flatten this into a smarter loop .
fn basin_size_search(map: &Vec2d<u8>,
                     basin: &mut HashMap<(usize, usize), usize>,
                     prev_point: (usize, usize),
                     point: (usize, usize),
                     verbose: bool,
                     ) -> usize {
    // Stop at '9' or out of bounds.
    if map.at(point).map_or(true, |h| *h == 9) {
        if verbose { println!("({:2}, {:2}) basin bounds", point.0, point.1); }
        0
    } else {
        // We might already have the sum from this point.
        if let Some(size) = basin.get(&point) {
            if verbose {
                println!(
                    "({:2}, {:2}) already know size from here = {}",
                    point.0, point.1, *size
                );
            }
            0
        } else {
            // Insert a dummy size before we recurse to implement a 'visited' check.
            basin.insert(point, usize::MAX);
            if verbose {
                println!("({:2}, {:2}) looking for basin size...", point.0, point.1);
            }
            // Visit the basin in every direction except the direction we just came from.
            let size = 1 + if up(point) != prev_point {
                basin_size_search(map, basin, point, up(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            + if left(point) != prev_point {
                basin_size_search(map, basin, point, left(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            + if right(point) != prev_point {
                basin_size_search(map, basin, point, right(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            + if down(point) != prev_point {
                basin_size_search(map, basin, point, down(point), verbose)
            } else { if verbose { println!("({:2}, {:2}) came from here, skipping -> 0", point.0, point.1); } 0 }
            ;
            basin.insert(point, size);
            if verbose {
                println!("({:2}, {:2}) found basin size {}", point.0, point.1, size);
            }
            size
        }
    }
}
fn basin_size_search ( map : & Vec2d < u8 > , basin : & mut HashMap < ( usize , usize ) , usize > , prev_point : ( usize , usize ) , point : ( usize , usize ) , verbose : bool , ) -> usize { // Stop at '9' or out of bounds. if map . at ( point ) . map_or ( true , | h | * h == 9 ) { if verbose { println ! ( " " point 0 point 1 ) ; } 0 } else { // We might already have the sum from this point. if let Some ( size ) = basin . get ( & point ) { if verbose { println ! ( " " point 0 point 1 size ) ; } 0 } else { // Insert a dummy size before we recurse to implement a 'visited' check. basin . insert ( point , usize :: MAX ) ; if verbose { println ! ( " " point 0 point 1 ) ; } // Visit the basin in every direction except the direction we just came from. let size = 1 + if up ( point ) != prev_point { basin_size_search ( map , basin , point , up ( point ) , verbose ) } else { if verbose { println ! ( " " point 0 point 1 ) ; } 0 } + if left ( point ) != prev_point { basin_size_search ( map , basin , point , left ( point ) , verbose ) } else { if verbose { println ! ( " " point 0 point 1 ) ; } 0 } + if right ( point ) != prev_point { basin_size_search ( map , basin , point , right ( point ) , verbose ) } else { if verbose { println ! ( " " point 0 point 1 ) ; } 0 } + if down ( point ) != prev_point { basin_size_search ( map , basin , point , down ( point ) , verbose ) } else { if verbose { println ! ( " " point 0 point 1 ) ; } 0 } ; basin . insert ( point , size ) ; if verbose { println ! ( " " point 0 point 1 size ) ; } size } } }
Love recursion, but this is awful for stack size.
Love recursion but this is awful for stack size .
map
&Vec2d<u8>
basin
&mut HashMap<(usize, usize), usize>
prev_point
(usize, usize)
point
(usize, usize)
verbose
bool