Move Day 8 to its own crate
This commit is contained in:
parent
c2243baf17
commit
f6793c685e
5 changed files with 75 additions and 45 deletions
14
2022/day8/Cargo.lock
generated
Normal file
14
2022/day8/Cargo.lock
generated
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day8"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"geometry",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "geometry"
|
||||||
|
version = "0.1.0"
|
9
2022/day8/Cargo.toml
Normal file
9
2022/day8/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "day8"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
geometry = { path = "../geometry" }
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::grid::{Direction, Point};
|
use geometry::{Direction, Point};
|
||||||
|
use std::{env, fs};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
/*
|
|
||||||
type UnsignedPoint = Point;
|
type UnsignedPoint = Point;
|
||||||
|
|
||||||
const INPUT: &'static str = include_str!("../../Data/day8-input.txt");
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Grid {
|
struct Grid {
|
||||||
grid: Vec<Vec<i8>>,
|
grid: Vec<Vec<i8>>,
|
||||||
|
@ -24,23 +22,23 @@ impl Grid {
|
||||||
self.grid[0].len()
|
self.grid[0].len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_height_at(&self, at: UnsignedPoint) -> Option<i8> {
|
fn tree_height_at(&self, at: &UnsignedPoint) -> Option<i8> {
|
||||||
Some(self.grid[at.y as usize][at.x as usize].clone())
|
Some(self.grid[at.y as usize][at.x as usize].clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scenic_score_at(&self, at: UnsignedPoint) -> i32 {
|
fn scenic_score_at(&self, at: &UnsignedPoint) -> i32 {
|
||||||
let height = self.tree_height_at(at);
|
let height = self.tree_height_at(at);
|
||||||
|
|
||||||
let mut scores = [0, 0, 0, 0];
|
let mut scores = [0, 0, 0, 0];
|
||||||
for (i, d) in Direction::all().iter().cloned().enumerate() {
|
for (i, d) in Direction::all().iter().cloned().enumerate() {
|
||||||
for pt in self.iter_points_from_point_to_edge_in_direction(at, d) {
|
for pt in self.iter_points_from_point_to_edge_in_direction(at, d) {
|
||||||
if pt == at {
|
if pt == *at {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
scores[i] += 1;
|
scores[i] += 1;
|
||||||
|
|
||||||
if self.tree_height_at(pt) >= height {
|
if self.tree_height_at(&pt) >= height {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,51 +57,57 @@ impl Grid {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_points_from_edge_to_point_in_direction(
|
fn iter_points_from_edge_to_point_in_direction<'a, 'b>(
|
||||||
&self,
|
&'a self,
|
||||||
point: UnsignedPoint,
|
point: &'b UnsignedPoint,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
) -> Box<dyn Iterator<Item = UnsignedPoint>> {
|
) -> Box<dyn Iterator<Item = UnsignedPoint> + 'a> {
|
||||||
let width = self.width() as i32;
|
let width = self.width() as i32;
|
||||||
let height = self.height() as i32;
|
let height = self.height() as i32;
|
||||||
|
|
||||||
|
let pt_x = point.x;
|
||||||
|
let pt_y = point.y;
|
||||||
|
|
||||||
let closure: Box<dyn Fn(i32) -> UnsignedPoint> = match direction {
|
let closure: Box<dyn Fn(i32) -> UnsignedPoint> = match direction {
|
||||||
Direction::North | Direction::South => {
|
Direction::North | Direction::South => {
|
||||||
Box::new(move |y| UnsignedPoint::new(point.x, y as i32))
|
Box::new(move |y| UnsignedPoint::new(pt_x, y as i32))
|
||||||
}
|
}
|
||||||
Direction::East | Direction::West => {
|
Direction::East | Direction::West => {
|
||||||
Box::new(move |x| UnsignedPoint::new(x as i32, point.y))
|
Box::new(move |x| UnsignedPoint::new(x as i32, pt_y))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match direction {
|
match direction {
|
||||||
Direction::North => Box::new((0..point.y).map(closure)),
|
Direction::North => Box::new((0..pt_y).map(closure)),
|
||||||
Direction::East => Box::new((point.x..width).rev().map(closure)),
|
Direction::East => Box::new((pt_x..width).rev().map(closure)),
|
||||||
Direction::South => Box::new((point.y..height).rev().map(closure)),
|
Direction::South => Box::new((pt_y..height).rev().map(closure)),
|
||||||
Direction::West => Box::new((0..point.x).map(closure)),
|
Direction::West => Box::new((0..pt_x).map(closure)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_points_from_point_to_edge_in_direction(
|
fn iter_points_from_point_to_edge_in_direction<'a, 'b>(
|
||||||
&self,
|
&'a self,
|
||||||
point: UnsignedPoint,
|
point: &'b UnsignedPoint,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
) -> Box<dyn Iterator<Item = UnsignedPoint>> {
|
) -> Box<dyn Iterator<Item = UnsignedPoint> + 'a> {
|
||||||
let width = self.width() as i32;
|
let width = self.width() as i32;
|
||||||
let height = self.height() as i32;
|
let height = self.height() as i32;
|
||||||
|
|
||||||
|
let pt_x = point.x;
|
||||||
|
let pt_y = point.y;
|
||||||
|
|
||||||
let closure: Box<dyn Fn(i32) -> UnsignedPoint> = match direction {
|
let closure: Box<dyn Fn(i32) -> UnsignedPoint> = match direction {
|
||||||
Direction::North | Direction::South => {
|
Direction::North | Direction::South => {
|
||||||
Box::new(move |y| UnsignedPoint::new(point.x, y as i32))
|
Box::new(move |y| UnsignedPoint::new(pt_x, y as i32))
|
||||||
}
|
}
|
||||||
Direction::East | Direction::West => Box::new(move |x| UnsignedPoint::new(x, point.y)),
|
Direction::East | Direction::West => Box::new(move |x| UnsignedPoint::new(x, pt_y)),
|
||||||
};
|
};
|
||||||
|
|
||||||
match direction {
|
match direction {
|
||||||
Direction::North => Box::new((0..point.y).rev().map(closure)),
|
Direction::North => Box::new((0..pt_y).rev().map(closure)),
|
||||||
Direction::East => Box::new((point.x..width).map(closure)),
|
Direction::East => Box::new((pt_x..width).map(closure)),
|
||||||
Direction::South => Box::new((point.y..height).map(closure)),
|
Direction::South => Box::new((pt_y..height).map(closure)),
|
||||||
Direction::West => Box::new((0..point.x).rev().map(closure)),
|
Direction::West => Box::new((0..pt_x).rev().map(closure)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +115,7 @@ impl Grid {
|
||||||
for y in 0..self.height() {
|
for y in 0..self.height() {
|
||||||
for x in 0..self.width() {
|
for x in 0..self.width() {
|
||||||
let pt = UnsignedPoint::new(x as i32, y as i32);
|
let pt = UnsignedPoint::new(x as i32, y as i32);
|
||||||
let height = self.tree_height_at(pt).unwrap();
|
let height = self.tree_height_at(&pt).unwrap();
|
||||||
if visible_trees.contains(&pt) {
|
if visible_trees.contains(&pt) {
|
||||||
print!("\x1B[32m{}\x1B[0m", height);
|
print!("\x1B[32m{}\x1B[0m", height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,12 +126,16 @@ impl Grid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn main(_filename: &str) -> std::io::Result<()> {
|
fn main() {
|
||||||
/*
|
let args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
let filename = args.get(1).expect("Missing filename argument");
|
||||||
|
|
||||||
|
let file_contents = fs::read_to_string(&filename).expect("Unable to read file");
|
||||||
|
|
||||||
let grid = Grid::new(
|
let grid = Grid::new(
|
||||||
INPUT
|
file_contents
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
l.chars()
|
l.chars()
|
||||||
|
@ -143,8 +151,8 @@ pub fn main(_filename: &str) -> std::io::Result<()> {
|
||||||
for grid_pt in grid.iter_points() {
|
for grid_pt in grid.iter_points() {
|
||||||
let mut tallest_tree_height: i8 = -1;
|
let mut tallest_tree_height: i8 = -1;
|
||||||
|
|
||||||
for pt in grid.iter_points_from_edge_to_point_in_direction(grid_pt, Direction::North) {
|
for pt in grid.iter_points_from_edge_to_point_in_direction(&grid_pt, Direction::North) {
|
||||||
let tree_height = grid.tree_height_at(pt).unwrap();
|
let tree_height = grid.tree_height_at(&pt).unwrap();
|
||||||
if tree_height > tallest_tree_height {
|
if tree_height > tallest_tree_height {
|
||||||
tallest_tree_height = tree_height;
|
tallest_tree_height = tree_height;
|
||||||
visible_trees.insert(pt);
|
visible_trees.insert(pt);
|
||||||
|
@ -152,8 +160,8 @@ pub fn main(_filename: &str) -> std::io::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
tallest_tree_height = -1;
|
tallest_tree_height = -1;
|
||||||
for pt in grid.iter_points_from_edge_to_point_in_direction(grid_pt, Direction::East) {
|
for pt in grid.iter_points_from_edge_to_point_in_direction(&grid_pt, Direction::East) {
|
||||||
let tree_height = grid.tree_height_at(pt).unwrap();
|
let tree_height = grid.tree_height_at(&pt).unwrap();
|
||||||
if tree_height > tallest_tree_height {
|
if tree_height > tallest_tree_height {
|
||||||
tallest_tree_height = tree_height;
|
tallest_tree_height = tree_height;
|
||||||
visible_trees.insert(pt);
|
visible_trees.insert(pt);
|
||||||
|
@ -161,8 +169,8 @@ pub fn main(_filename: &str) -> std::io::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
tallest_tree_height = -1;
|
tallest_tree_height = -1;
|
||||||
for pt in grid.iter_points_from_edge_to_point_in_direction(grid_pt, Direction::South) {
|
for pt in grid.iter_points_from_edge_to_point_in_direction(&grid_pt, Direction::South) {
|
||||||
let tree_height = grid.tree_height_at(pt).unwrap();
|
let tree_height = grid.tree_height_at(&pt).unwrap();
|
||||||
if tree_height > tallest_tree_height {
|
if tree_height > tallest_tree_height {
|
||||||
tallest_tree_height = tree_height;
|
tallest_tree_height = tree_height;
|
||||||
visible_trees.insert(pt);
|
visible_trees.insert(pt);
|
||||||
|
@ -170,23 +178,22 @@ pub fn main(_filename: &str) -> std::io::Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
tallest_tree_height = -1;
|
tallest_tree_height = -1;
|
||||||
for pt in grid.iter_points_from_edge_to_point_in_direction(grid_pt, Direction::West) {
|
for pt in grid.iter_points_from_edge_to_point_in_direction(&grid_pt, Direction::West) {
|
||||||
let tree_height = grid.tree_height_at(pt).unwrap();
|
let tree_height = grid.tree_height_at(&pt).unwrap();
|
||||||
if tree_height > tallest_tree_height {
|
if tree_height > tallest_tree_height {
|
||||||
tallest_tree_height = tree_height;
|
tallest_tree_height = tree_height;
|
||||||
visible_trees.insert(pt);
|
visible_trees.insert(pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let scenic_score = grid.scenic_score_at(grid_pt);
|
let scenic_score = grid.scenic_score_at(&grid_pt);
|
||||||
if scenic_score > highest_scenic_score {
|
if scenic_score > highest_scenic_score {
|
||||||
highest_scenic_score = scenic_score;
|
highest_scenic_score = scenic_score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grid.print_with_visible_set(&visible_trees);
|
||||||
|
println!("");
|
||||||
println!("Part 1: Number of visible trees: {}", &visible_trees.len());
|
println!("Part 1: Number of visible trees: {}", &visible_trees.len());
|
||||||
println!("Part 2: Highest scenic score: {}", highest_scenic_score);
|
println!("Part 2: Highest scenic score: {}", highest_scenic_score);
|
||||||
*/
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue