diff --git a/2022/day8/Cargo.lock b/2022/day8/Cargo.lock new file mode 100644 index 0000000..af0ca8c --- /dev/null +++ b/2022/day8/Cargo.lock @@ -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" diff --git a/2022/day8/Cargo.toml b/2022/day8/Cargo.toml new file mode 100644 index 0000000..07b4cd7 --- /dev/null +++ b/2022/day8/Cargo.toml @@ -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" } diff --git a/2022/aoc2022/data/day8-input-example.txt b/2022/day8/example.txt similarity index 100% rename from 2022/aoc2022/data/day8-input-example.txt rename to 2022/day8/example.txt diff --git a/2022/aoc2022/data/day8-input.txt b/2022/day8/input.txt similarity index 100% rename from 2022/aoc2022/data/day8-input.txt rename to 2022/day8/input.txt diff --git a/2022/aoc2022/src/day8.rs b/2022/day8/src/main.rs similarity index 65% rename from 2022/aoc2022/src/day8.rs rename to 2022/day8/src/main.rs index e68244e..1a3dcdd 100644 --- a/2022/aoc2022/src/day8.rs +++ b/2022/day8/src/main.rs @@ -1,11 +1,9 @@ -use crate::grid::{Direction, Point}; +use geometry::{Direction, Point}; +use std::{env, fs}; use std::collections::HashSet; -/* type UnsignedPoint = Point; -const INPUT: &'static str = include_str!("../../Data/day8-input.txt"); - #[derive(Debug)] struct Grid { grid: Vec>, @@ -24,23 +22,23 @@ impl Grid { self.grid[0].len() } - fn tree_height_at(&self, at: UnsignedPoint) -> Option { + fn tree_height_at(&self, at: &UnsignedPoint) -> Option { 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 mut scores = [0, 0, 0, 0]; for (i, d) in Direction::all().iter().cloned().enumerate() { for pt in self.iter_points_from_point_to_edge_in_direction(at, d) { - if pt == at { + if pt == *at { continue; } scores[i] += 1; - if self.tree_height_at(pt) >= height { + if self.tree_height_at(&pt) >= height { break; } } @@ -59,51 +57,57 @@ impl Grid { ) } - fn iter_points_from_edge_to_point_in_direction( - &self, - point: UnsignedPoint, + fn iter_points_from_edge_to_point_in_direction<'a, 'b>( + &'a self, + point: &'b UnsignedPoint, direction: Direction, - ) -> Box> { + ) -> Box + 'a> { let width = self.width() as i32; let height = self.height() as i32; + let pt_x = point.x; + let pt_y = point.y; + let closure: Box UnsignedPoint> = match direction { 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 as i32, point.y)) + Box::new(move |x| UnsignedPoint::new(x as i32, pt_y)) } }; match direction { - Direction::North => Box::new((0..point.y).map(closure)), - Direction::East => Box::new((point.x..width).rev().map(closure)), - Direction::South => Box::new((point.y..height).rev().map(closure)), - Direction::West => Box::new((0..point.x).map(closure)), + Direction::North => Box::new((0..pt_y).map(closure)), + Direction::East => Box::new((pt_x..width).rev().map(closure)), + Direction::South => Box::new((pt_y..height).rev().map(closure)), + Direction::West => Box::new((0..pt_x).map(closure)), } } - fn iter_points_from_point_to_edge_in_direction( - &self, - point: UnsignedPoint, + fn iter_points_from_point_to_edge_in_direction<'a, 'b>( + &'a self, + point: &'b UnsignedPoint, direction: Direction, - ) -> Box> { + ) -> Box + 'a> { let width = self.width() as i32; let height = self.height() as i32; + let pt_x = point.x; + let pt_y = point.y; + let closure: Box UnsignedPoint> = match direction { 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 { - Direction::North => Box::new((0..point.y).rev().map(closure)), - Direction::East => Box::new((point.x..width).map(closure)), - Direction::South => Box::new((point.y..height).map(closure)), - Direction::West => Box::new((0..point.x).rev().map(closure)), + Direction::North => Box::new((0..pt_y).rev().map(closure)), + Direction::East => Box::new((pt_x..width).map(closure)), + Direction::South => Box::new((pt_y..height).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 x in 0..self.width() { 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) { print!("\x1B[32m{}\x1B[0m", height); } else { @@ -122,12 +126,16 @@ impl Grid { } } } -*/ -pub fn main(_filename: &str) -> std::io::Result<()> { - /* +fn main() { + let args: Vec = 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( - INPUT + file_contents .lines() .map(|l| { l.chars() @@ -143,8 +151,8 @@ pub fn main(_filename: &str) -> std::io::Result<()> { for grid_pt in grid.iter_points() { let mut tallest_tree_height: i8 = -1; - 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(); + 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(); if tree_height > tallest_tree_height { tallest_tree_height = tree_height; visible_trees.insert(pt); @@ -152,8 +160,8 @@ pub fn main(_filename: &str) -> std::io::Result<()> { } tallest_tree_height = -1; - 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(); + 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(); if tree_height > tallest_tree_height { tallest_tree_height = tree_height; visible_trees.insert(pt); @@ -161,8 +169,8 @@ pub fn main(_filename: &str) -> std::io::Result<()> { } tallest_tree_height = -1; - 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(); + 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(); if tree_height > tallest_tree_height { tallest_tree_height = tree_height; visible_trees.insert(pt); @@ -170,23 +178,22 @@ pub fn main(_filename: &str) -> std::io::Result<()> { } tallest_tree_height = -1; - 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(); + 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(); if tree_height > tallest_tree_height { tallest_tree_height = tree_height; 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 { 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 2: Highest scenic score: {}", highest_scenic_score); - */ - - Ok(()) }