main.rs (2464B)
1 fn main() { 2 let input = std::fs::read_to_string("input.txt") 3 .unwrap() 4 .trim() 5 .split("\n") 6 .map(|x| x.chars().map(|c| c.to_digit(10).unwrap()).collect()) 7 .collect::<Vec<Vec<u32>>>(); 8 // 1789 9 println!("Part 1: {}", part_1(&input)); 10 // 314820 11 println!("Part 2: {}", part_2(&input)); 12 } 13 14 fn is_visible(input: &Vec<Vec<u32>>, x: usize, y: usize) -> bool { 15 (0..x).all(|i| input[i][y] < input[x][y]) 16 || ((x + 1)..input.len()).all(|i| input[i][y] < input[x][y]) 17 || (0..y).all(|j| input[x][j] < input[x][y]) 18 || ((y + 1)..input[0].len()).all(|j| input[x][j] < input[x][y]) 19 } 20 21 fn part_1(input: &Vec<Vec<u32>>) -> usize { 22 let mut visible_count = 0; 23 for x in 0..input.len() { 24 for y in 0..input[0].len() { 25 if is_visible(input, x, y) { 26 visible_count += 1; 27 } 28 } 29 } 30 visible_count 31 } 32 33 fn calc_scenic_score(input: &Vec<Vec<u32>>, x: usize, y: usize) -> usize { 34 (0..x) 35 .rev() 36 .scan(0, |max, i| { 37 if *max < input[x][y] { 38 *max = input[i][y]; 39 Some(()) 40 } else { 41 None 42 } 43 }) 44 .fuse() 45 .count() 46 * ((x + 1)..input.len()) 47 .scan(0, |max, i| { 48 if *max < input[x][y] { 49 *max = input[i][y]; 50 Some(()) 51 } else { 52 None 53 } 54 }) 55 .fuse() 56 .count() 57 * (0..y) 58 .rev() 59 .scan(0, |max, j| { 60 if *max < input[x][y] { 61 *max = input[x][j]; 62 Some(()) 63 } else { 64 None 65 } 66 }) 67 .fuse() 68 .count() 69 * ((y + 1)..input[0].len()) 70 .scan(0, |max, j| { 71 if *max < input[x][y] { 72 *max = input[x][j]; 73 Some(()) 74 } else { 75 None 76 } 77 }) 78 .fuse() 79 .count() 80 } 81 82 fn part_2(input: &Vec<Vec<u32>>) -> usize { 83 let mut max_score = 0; 84 for x in 0..input.len() { 85 for y in 0..input[0].len() { 86 let score = calc_scenic_score(input, x, y); 87 if score > max_score { 88 max_score = score; 89 } 90 } 91 } 92 max_score 93 }