add day 8
This commit is contained in:
parent
6abb28f96f
commit
2e2d668269
@ -35,6 +35,10 @@ path = "src/day6.rs"
|
||||
name = "day7"
|
||||
path = "src/day7.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "day8"
|
||||
path = "src/day8.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
93
2022/src/day8.rs
Normal file
93
2022/src/day8.rs
Normal file
@ -0,0 +1,93 @@
|
||||
const DATA: &'static str = include_str!("../data/day8.txt");
|
||||
// const DATA: &'static str = "
|
||||
// 30373
|
||||
// 25512
|
||||
// 65332
|
||||
// 33549
|
||||
// 35390
|
||||
// ";
|
||||
|
||||
|
||||
// O(N * (2 * sqrt(N) - 1)), so roughly N^1.5? Where N is number of elements in the grid
|
||||
fn is_visible(grid: &Vec<Vec<usize>>, x: usize, y: usize) -> bool {
|
||||
let height = grid[y][x];
|
||||
let rows = grid.len();
|
||||
let cols = grid[x].len();
|
||||
// search horizontal
|
||||
let vis_left = (0..x).all(|cmp_x| grid[y][cmp_x] < height);
|
||||
let vis_right = ((x + 1)..cols).all(|cmp_x| grid[y][cmp_x] < height);
|
||||
|
||||
let vis_top = (0..y).all(|cmp_y| grid[cmp_y][x] < height);
|
||||
let vis_bottom = ((y + 1)..rows).all(|cmp_y| grid[cmp_y][x] < height);
|
||||
|
||||
vis_left || vis_right || vis_top || vis_bottom
|
||||
}
|
||||
|
||||
|
||||
fn scenic_score(grid: &Vec<Vec<usize>>, x: usize, y: usize) -> usize {
|
||||
let height = grid[y][x];
|
||||
let rows = grid.len();
|
||||
let cols = grid[x].len();
|
||||
|
||||
let sc_left = (0..x).rev()
|
||||
.position(|cmp_x| grid[y][cmp_x] >= height) // 0-indexed position of the first blocking tree
|
||||
.map(|p| p + 1) // +1 since we include the blocking tree in the count
|
||||
.unwrap_or(x); // if no blocking trees, score is how many are to the left of current
|
||||
|
||||
let sc_right = ((x + 1)..cols)
|
||||
.position(|cmp_x| grid[y][cmp_x] >= height)
|
||||
.map(|p| p + 1)
|
||||
.unwrap_or(cols - x - 1); // e.g. if x is 4 and there are 5 cols, this is rightmost, so 5 - 4 - 1 = 0
|
||||
|
||||
let sc_top = (0..y).rev()
|
||||
.position(|cmp_y| grid[cmp_y][x] >= height)
|
||||
.map(|p| p + 1)
|
||||
.unwrap_or(y);
|
||||
|
||||
let sc_bottom = ((y + 1)..rows)
|
||||
.position(|cmp_y| grid[cmp_y][x] >= height)
|
||||
.map(|p| p + 1)
|
||||
.unwrap_or(rows - y - 1);
|
||||
|
||||
sc_left * sc_right * sc_top * sc_bottom
|
||||
}
|
||||
|
||||
|
||||
fn build_grid(data: &str) -> Result<Vec<Vec<usize>>, String> {
|
||||
data.trim()
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
.map(|c| c.to_digit(10).map(|c| c as usize).ok_or_else(|| format!("Failed to convert to integer: {c}") ))
|
||||
.collect::<Result<Vec<usize>, String>>()
|
||||
})
|
||||
.collect::<Result<Vec<Vec<usize>>, String>>()
|
||||
}
|
||||
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let grid = build_grid(DATA)?;
|
||||
|
||||
let mut visible_trees = 0;
|
||||
for y in 0..grid.len() {
|
||||
for x in 0..grid[y].len() {
|
||||
if is_visible(&grid, x, y) {
|
||||
visible_trees += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Part 1: {visible_trees}");
|
||||
|
||||
let mut max_score = 0;
|
||||
for y in 0..grid.len() {
|
||||
for x in 0..grid[y].len() {
|
||||
let score = scenic_score(&grid, x, y);
|
||||
if score > max_score {
|
||||
max_score = score;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("Part 2: {max_score}");
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user