Lots of progress on day 8 part 1
This commit is contained in:
parent
aced557148
commit
fcae876701
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
The expedition comes across a peculiar patch of tall trees all planted carefully in a grid. The Elves explain that a previous expedition planted these trees as a reforestation effort. Now, they're curious if this would be a good location for a tree house.
|
The expedition comes across a peculiar patch of tall trees all planted carefully in a grid. The Elves explain that a previous expedition planted these trees as a reforestation effort. Now, they're curious if this would be a good location for a tree house.
|
||||||
|
|
||||||
First, determine whether there is enough tree cover here to keep a tree house hidden. To do this, you need to count the number of trees that are visible from outside the grid when looking directly along a row or column.
|
First, determine whether there is enough tree cover here to keep a tree house **hidden**. To do this, you need to count the number of trees that are **visible from outside the grid** when looking directly along a row or column.
|
||||||
|
|
||||||
The Elves have already launched a quadcopter to generate a map with the height of each tree (your puzzle input). For example:
|
The Elves have already launched a quadcopter to generate a map with the height of each tree (your puzzle input). For example:
|
||||||
|
|
||||||
@ -16,18 +16,18 @@ The Elves have already launched a quadcopter to generate a map with the height o
|
|||||||
|
|
||||||
Each tree is represented as a single digit whose value is its height, where 0 is the shortest and 9 is the tallest.
|
Each tree is represented as a single digit whose value is its height, where 0 is the shortest and 9 is the tallest.
|
||||||
|
|
||||||
A tree is visible if all of the other trees between it and an edge of the grid are shorter than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree.
|
A tree is **visible** if all of the other trees between it and an edge of the grid are **shorter** than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree.
|
||||||
|
|
||||||
All of the trees around the edge of the grid are visible - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the interior nine trees to consider:
|
All of the trees around the edge of the grid are **visible** - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the **interior nine trees** to consider:
|
||||||
|
|
||||||
* The top-left 5 is visible from the left and top. (It isn't visible from the right or bottom since other trees of height 5 are in the way.)
|
* The top-left 5 is **visible** from the left and top. (It isn't visible from the right or bottom since other trees of height 5 are in the way.)
|
||||||
* The top-middle 5 is visible from the top and right.
|
* The top-middle 5 is **visible** from the top and right.
|
||||||
* The top-right 1 is not visible from any direction; for it to be visible, there would need to only be trees of height 0 between it and an edge.
|
* The top-right 1 is not visible from any direction; for it to be visible, there would need to only be trees of height **0** between it and an edge.
|
||||||
* The left-middle 5 is visible, but only from the right.
|
* The left-middle 5 is **visible**, but only from the right.
|
||||||
* The center 3 is not visible from any direction; for it to be visible, there would need to be only trees of at most height 2 between it and an edge.
|
* The center 3 is not visible from any direction; for it to be visible, there would need to be only trees of at most height 2 between it and an edge.
|
||||||
* The right-middle 3 is visible from the right.
|
* The right-middle 3 is **visible** from the right.
|
||||||
* In the bottom row, the middle 5 is visible, but the 3 and 4 are not.
|
* In the bottom row, the middle 5 is **visible**, but the 3 and 4 are not.
|
||||||
|
|
||||||
With 16 trees visible on the edge and another 5 visible in the interior, a total of 21 trees are visible in this arrangement.
|
With 16 trees visible on the edge and another 5 visible in the interior, a total of 21 trees are visible in this arrangement.
|
||||||
|
|
||||||
Consider your map; how many trees are visible from outside the grid?
|
**Consider your map; how many trees are visible from outside the grid?**
|
||||||
|
197
day8/src/main.rs
197
day8/src/main.rs
@ -1,8 +1,203 @@
|
|||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Hash)]
|
||||||
|
enum VisibleDirection {
|
||||||
|
Top,
|
||||||
|
Bottom,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
|
use VisibleDirection::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct Tree {
|
||||||
|
height: usize,
|
||||||
|
visible: HashSet<VisibleDirection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tree {
|
||||||
|
fn new(height: usize) -> Self {
|
||||||
|
Tree {
|
||||||
|
height,
|
||||||
|
..Tree::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_visible(&self) -> bool {
|
||||||
|
!self.visible.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_visible(&mut self, dir: VisibleDirection) -> &mut Self {
|
||||||
|
self.visible.insert(dir);
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_all_visible(&mut self) -> &mut Self {
|
||||||
|
self.set_visible(Top)
|
||||||
|
.set_visible(Bottom)
|
||||||
|
.set_visible(Left)
|
||||||
|
.set_visible(Right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Grid<T> {
|
||||||
|
width: usize,
|
||||||
|
vec: Vec<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Grid<T> {
|
||||||
|
fn new(width: usize) -> Self {
|
||||||
|
Grid {
|
||||||
|
width,
|
||||||
|
vec: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert x,y coordinate into linear array index
|
||||||
|
fn xy_idx(&self, x: usize, y: usize) -> usize {
|
||||||
|
(y * self.width) + x
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert linear array index to x,y coordinate
|
||||||
|
fn idx_xy(&self, idx: usize) -> (usize, usize) {
|
||||||
|
(idx % self.width, idx / self.width)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn row_first_idx(&self, row: usize) -> usize {
|
||||||
|
let idx = row * self.width;
|
||||||
|
|
||||||
|
if idx < self.vec.len() {
|
||||||
|
idx
|
||||||
|
} else {
|
||||||
|
self.vec.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn row_last_idx(&self, row: usize) -> usize {
|
||||||
|
if (row + 1) > self.num_rows() {
|
||||||
|
return self.vec.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.row_first_idx(row + 1) - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn num_rows(&self) -> usize {
|
||||||
|
let even_rows = self.vec.len() / self.width;
|
||||||
|
|
||||||
|
if self.vec.len() % self.width > 0 {
|
||||||
|
even_rows + 1
|
||||||
|
} else {
|
||||||
|
even_rows
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn num_cols(&self) -> usize {
|
||||||
|
self.width
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_row(&mut self, row_num: usize) -> &mut [T] {
|
||||||
|
let start = self.row_first_idx(row_num);
|
||||||
|
let end = self.row_last_idx(row_num);
|
||||||
|
|
||||||
|
&mut self.vec[start..=end]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_column_indexes(&self, col_num: usize) -> Vec<usize> {
|
||||||
|
let mut indexes = Vec::new();
|
||||||
|
|
||||||
|
if col_num > self.num_cols() {
|
||||||
|
return indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
for r in 0..self.num_rows() {
|
||||||
|
let idx = self.width * r + col_num;
|
||||||
|
indexes.push(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Grid<Tree> {
|
||||||
|
fn mark_outer_trees_visible(&mut self) {
|
||||||
|
fn set_row_visible(row: &mut [Tree]) {
|
||||||
|
row.iter_mut().for_each(|tree| { tree.set_all_visible(); })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set top/bottom rows as visible
|
||||||
|
set_row_visible(self.get_row(0));
|
||||||
|
set_row_visible(self.get_row(self.num_rows() - 1));
|
||||||
|
|
||||||
|
// Set left/right cols as visible
|
||||||
|
self.get_column_indexes(0).into_iter().for_each(|id| {
|
||||||
|
self.vec[id].set_all_visible();
|
||||||
|
});
|
||||||
|
self.get_column_indexes(self.num_cols() - 1).into_iter().for_each(|id| {
|
||||||
|
self.vec[id].set_all_visible();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mark_visible_trees(&mut self) {
|
||||||
|
self.mark_outer_trees_visible();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_visible_trees(&self) -> usize {
|
||||||
|
self
|
||||||
|
.vec
|
||||||
|
.iter()
|
||||||
|
.filter(|tree| tree.is_visible())
|
||||||
|
.collect::<Vec<&Tree>>()
|
||||||
|
.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_file_str(file_str: &'static str) -> Grid<Tree> {
|
||||||
|
let lines: Vec<&str> = file_str.lines().collect();
|
||||||
|
let width = lines[0].len();
|
||||||
|
let mut grid: Grid<Tree> = Grid::new(width);
|
||||||
|
|
||||||
|
for line in lines {
|
||||||
|
let mut row: Vec<Tree> = line
|
||||||
|
.chars()
|
||||||
|
.map(|ch| Tree::new(ch.to_digit(10).unwrap() as usize))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
grid.vec.append(&mut row);
|
||||||
|
}
|
||||||
|
|
||||||
|
grid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let file_str = include_str!("input.txt");
|
let file_str = include_str!("input.txt");
|
||||||
|
let mut grid = Grid::from_file_str(file_str);
|
||||||
|
grid.mark_visible_trees();
|
||||||
|
let visible_num = grid.get_visible_trees();
|
||||||
|
|
||||||
|
println!("Part 1: Number of visible trees: {}", visible_num);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
}
|
|
||||||
|
fn get_data() -> &'static str {
|
||||||
|
include_str!("test-input.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_outer_visible_trees() {
|
||||||
|
let mut grid = Grid::from_file_str(get_data());
|
||||||
|
grid.mark_outer_trees_visible();
|
||||||
|
|
||||||
|
assert_eq!(grid.get_visible_trees(), 16usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
5
day8/src/test-input.txt
Normal file
5
day8/src/test-input.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
30373
|
||||||
|
25512
|
||||||
|
65332
|
||||||
|
33549
|
||||||
|
35390
|
Reference in New Issue
Block a user