fn main() { let contents = std::fs::read_to_string("data.txt").expect("Failed to read file"); let grid = contents // make it a grid of u32 .lines() .map(|l| { l.chars() .map(|c| c.to_digit(10).unwrap()) .collect::>() }) .collect::>>(); let height = grid.len(); let mut visible = 0; let mut high_score = 0; for (row, line) in grid.iter().enumerate() { for (col, tree) in line.iter().enumerate() { let width = line.len(); let north = (0..row).map(|r| grid[r][col]).rev().collect::>(); let south = (row + 1..height) .map(|r| grid[r][col]) .collect::>(); let west = (0..col).map(|c| grid[row][c]).rev().collect::>(); let east = (col + 1..width).map(|c| grid[row][c]).collect::>(); let dirs = vec![north, south, west, east]; // Part 1 if row == 0 || col == 0 || row == height - 1 || col == width - 1 { visible += 1; // if it is on the edge, it is visible } else { if dirs.iter().any(|dir| dir.iter().all(|t| tree > t)) { visible += 1; } } // Part 2 let score = dirs.iter().fold(1, |acc, dir| { let position = dir.into_iter().position(|x| tree <= x); acc * match position { Some(x) => x + 1, None => dir.len(), // hit an edge. return the distance to the edge } }); if score > high_score { high_score = score; } } } println!("Number Visible: {:?}", visible); println!("Highest Score: {:?}", high_score); }