use std::error; use std::fs::File; use std::io::BufRead; use std::io::BufReader; fn main() -> Result<(), Box> { let f = File::open("input.txt")?; let reader = BufReader::new(f); let mut map = vec![]; let mut width = 0; for line in reader.lines() { let line = line?; width = line.len(); map.extend(line.chars().map(|c| c.to_digit(10)).flatten().map(|d| d as usize)); } let width = width; let height = map.len() / width; let mut scenic_scores = vec![]; for i in 0..map.len() { let line = i / height; let column = i % width + 1; // we need + 1 here, because there is no modulo 0 let mut scenic_score = 1; // tree-houses cannot be built on the outside, so we have to skip those outside-trees for // the calculation if line == 0 || line == height - 1 || column == 1 || column == width { continue; } // println!("line: {}, column: {}, self: {}", line, column, map[i]); let left = map[(line * width)..i].iter() .rev() .scan(true, |state, &x| if !*state { None } else { if x >= map[i] { *state = false }; Some(1) }) // .inspect(|x| println!("{x}")) .count(); if left > 0 { scenic_score *= left; } let right = map[i..((line + 1) * width)].iter() .enumerate() .filter_map(|(j, x)| if (j + i) / height == line && j > 0 { Some(x) } else { None }) .scan(true, |state, &x| if !*state { None } else { if x >= map[i] { *state = false }; Some(1) }) .count(); if right > 0 { scenic_score *= right; } // let right = map[(i + 1)..((line + 1) * width)].iter().max(); let up = map[0..i].iter() .enumerate() //.inspect(|(j, x)| println!("{j} {x}")) .filter_map(|(j, x)| if (j + 1) % width == column { Some(x) } else { None }) .rev() .scan(true, |state, &x| if !*state { None } else { if x >= map[i] { *state = false }; Some(1) }) .count(); if up > 0 { scenic_score *= up; } let down = map[i..].iter() .enumerate() .filter_map(|(j, x)| if (i + j + 1) % width == column && j > 0 { Some(x) } else { None }) .scan(true, |state, &x| if !*state { None } else { if x >= map[i] { *state = false }; Some(1) }) .count(); if down > 0 { scenic_score *= down; } // println!("left: {:?}, right: {:?}, up: {:?}, down: {:?}", &left, &right, &up, &down); /* for direction_max in vec![left, right, up, down] { match direction_max { Some(x) if x < &map[i] => { visible_count += 1; break; }, None => { visible_count += 1; break; }, _ => () } } */ scenic_scores.push(scenic_score); } println!("Highest scenic score is {}", scenic_scores.iter().max().unwrap_or(&0)); Ok(()) }