Skip to content

Commit

Permalink
Completed day 08
Browse files Browse the repository at this point in the history
Since rust doest have an inclusive "take_while"
(rust-lang/rust#62208) for iterators I had to
use an extra crate (https://crates.io/crates/take-until), which is
something I don't particularly like as I believe crates should do
something more than just adding a single thing.

Oh, well, they'll add it!
  • Loading branch information
Jazzinghen committed Dec 8, 2022
1 parent ab41c97 commit fd6fcbb
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ nalgebra = "0.31.4"
nom = "7.1.1"
petgraph = "0.6.2"
rayon = "1.6"
take-until = "0.1.0"
3 changes: 2 additions & 1 deletion src/year_2022.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod day04;
mod day05;
mod day06;
mod day07;
mod day08;

use crate::aoc_lib::DayFn;

Expand All @@ -17,7 +18,7 @@ pub fn get_day(day: u8) -> (Option<DayFn>, Option<DayFn>) {
5 => (Some(day05::part1), Some(day05::part2)),
6 => (Some(day06::part1), Some(day06::part2)),
7 => (Some(day07::part1), Some(day07::part2)),
8 => (None, None),
8 => (Some(day08::part1), Some(day08::part2)),
9 => (None, None),
10 => (None, None),
11 => (None, None),
Expand Down
172 changes: 172 additions & 0 deletions src/year_2022/day08.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
use nalgebra::DMatrix;
use take_until::TakeUntilExt;

#[derive(Eq, PartialEq, Debug, Clone)]
struct Forest {
tree_heights: DMatrix<u8>,
}

impl Forest {
fn new(input: &str) -> Self {
let rows = input.lines().count();
let columns = input.lines().next().unwrap().len();
let tree_heights: DMatrix<u8> = DMatrix::from_row_iterator(
rows,
columns,
input
.chars()
.filter_map(|c| c.to_digit(10).and_then(|d| d.try_into().ok())),
);

Self { tree_heights }
}

pub fn visible_trees(&self) -> usize {
let mut visible_matix: DMatrix<bool> =
DMatrix::from_element(self.tree_heights.nrows(), self.tree_heights.ncols(), false);

for cell in visible_matix.row_mut(0).iter_mut() {
*cell = true;
}

for cell in visible_matix.row_mut(visible_matix.nrows() - 1).iter_mut() {
*cell = true;
}

for cell in visible_matix.column_mut(0).iter_mut() {
*cell = true;
}

for cell in visible_matix
.column_mut(visible_matix.ncols() - 1)
.iter_mut()
{
*cell = true;
}

for (row_id, row) in self.tree_heights.row_iter().enumerate() {
let mut max_height = row[0];
for (col_id, cell) in row.iter().enumerate().skip(1) {
if *cell > max_height {
visible_matix[(row_id, col_id)] |= true;
max_height = *cell;
}
}

max_height = row[row.len() - 1];
for (col_id, cell) in row.iter().enumerate().rev().skip(1) {
if *cell > max_height {
visible_matix[(row_id, col_id)] |= true;
max_height = *cell;
}
}
}

for (col_id, col) in self.tree_heights.column_iter().enumerate() {
let mut max_height = col[0];
for (row_id, cell) in col.iter().enumerate().skip(1) {
if *cell > max_height {
visible_matix[(row_id, col_id)] |= true;
max_height = *cell;
}
}

max_height = col[col.len() - 1];
for (row_id, cell) in col.iter().enumerate().rev().skip(1) {
if *cell > max_height {
visible_matix[(row_id, col_id)] |= true;
max_height = *cell;
}
}
}

visible_matix.iter().filter(|&&v| v).count()
}

pub fn scenic_score(&self) -> usize {
let mut max_scenic: usize = 0;

for (cell_id, cell) in self.tree_heights.iter().enumerate() {
let (row, col) = self.tree_heights.vector_to_matrix_index(cell_id);

let left_view: usize = self
.tree_heights
.row(row)
.iter()
.take(col)
.rev()
.take_until(|&h| *h >= *cell)
.count();

let right_view: usize = self
.tree_heights
.row(row)
.iter()
.skip(col + 1)
.take_until(|&h| *h >= *cell)
.count();

let top_view: usize = self
.tree_heights
.column(col)
.iter()
.take(row)
.rev()
.take_until(|&h| *h >= *cell)
.count();

let bottom_view: usize = self
.tree_heights
.column(col)
.iter()
.skip(row + 1)
.take_until(|&h| *h >= *cell)
.count();

let scenic_score = left_view * right_view * top_view * bottom_view;

max_scenic = max_scenic.max(scenic_score);
}

max_scenic
}
}

pub fn part1(input: &str) {
let forest = Forest::new(input);
let visible_trees = forest.visible_trees();
println!("Visible trees: {}", visible_trees);
}

pub fn part2(input: &str) {
let forest = Forest::new(input);
let maximum_scenic_score = forest.scenic_score();
println!("Maximum scenic score: {}", maximum_scenic_score);
}

#[cfg(test)]
mod tests {
use super::*;

static INPUT_STRING: &str = "30373
25512
65332
33549
35390";

#[test]
fn simple_visible() {
let forest = Forest::new(INPUT_STRING);
let visible_trees = forest.visible_trees();

assert_eq!(visible_trees, 21);
}

#[test]
fn simple_scenic() {
let forest = Forest::new(INPUT_STRING);
let maximum_scenic_score = forest.scenic_score();

assert_eq!(maximum_scenic_score, 8);
}
}

0 comments on commit fd6fcbb

Please sign in to comment.