add day 8
This commit is contained in:
		
							
								
								
									
										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(())
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user