summaryrefslogtreecommitdiff
path: root/2023/src/bin/day_18.rs
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-12-27 16:46:10 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-12-27 16:46:10 +0200
commit705e1a6ab99ee3292f8861b70664bfd0d7c2ea1a (patch)
tree58178532fd9ae638eb073b55a897d4942aebe9c0 /2023/src/bin/day_18.rs
parent33a20bfd9402397530dc3efd5607b9a9d8b28f34 (diff)
Days 21 and 18 part 2
Diffstat (limited to '2023/src/bin/day_18.rs')
-rw-r--r--2023/src/bin/day_18.rs45
1 files changed, 36 insertions, 9 deletions
diff --git a/2023/src/bin/day_18.rs b/2023/src/bin/day_18.rs
index c3e9f58..a4c9355 100644
--- a/2023/src/bin/day_18.rs
+++ b/2023/src/bin/day_18.rs
@@ -16,9 +16,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut fill_map = parsed.draw_map();
fill_map.derive_inside_outside();
dbg!(&fill_map.count_inside());
+ dbg!(&parsed.find_internal_area());
let hex_parsed = Instructions::hex_parser(&input).unwrap().1;
- dbg!(&hex_parsed);
+ dbg!(&hex_parsed.find_internal_area());
+
Ok(())
}
@@ -27,15 +29,15 @@ struct Instructions(Vec<Instruction>);
#[derive(Debug)]
struct Instruction {
- direction: Vector2<i32>,
+ direction: Vector2<i64>,
distance: u32,
}
#[derive(Debug)]
struct FloodFillMap {
- map: HashMap<Point2<i32>, Fill>,
- top_left: Point2<i32>,
- bottom_right: Point2<i32>,
+ map: HashMap<Point2<i64>, Fill>,
+ top_left: Point2<i64>,
+ bottom_right: Point2<i64>,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -71,6 +73,31 @@ impl Instructions {
FloodFillMap::new(trench)
}
+
+ fn find_internal_area(&self) -> i64 {
+ let mut current_point = Point2::new(0, 0);
+ let mut points = vec![current_point];
+
+ let mut perimeter = 0;
+ for instruction in &self.0 {
+ let next_point = current_point + instruction.direction * instruction.distance as i64;
+ points.push(next_point);
+ current_point = next_point;
+ perimeter += instruction.distance as i64;
+ }
+
+ let mut area = 0;
+ for point in points.windows(2) {
+ if let &[p1, p2] = point {
+ area += p1.x * p2.y;
+ area -= p1.y * p2.x;
+ } else {
+ unreachable!()
+ }
+ }
+
+ (perimeter + 2 + area) / 2
+ }
}
impl Instruction {
@@ -112,7 +139,7 @@ impl Instruction {
}
}
-fn dir_parser(input: &str) -> IResult<&str, Vector2<i32>> {
+fn dir_parser(input: &str) -> IResult<&str, Vector2<i64>> {
alt((
value(Vector2::new(0, -1), char('U')),
value(Vector2::new(0, 1), char('D')),
@@ -121,7 +148,7 @@ fn dir_parser(input: &str) -> IResult<&str, Vector2<i32>> {
))(input)
}
-fn hex_dir_parser(input: &str) -> IResult<&str, Vector2<i32>> {
+fn hex_dir_parser(input: &str) -> IResult<&str, Vector2<i64>> {
alt((
value(Vector2::new(0, -1), char('3')),
value(Vector2::new(0, 1), char('1')),
@@ -131,7 +158,7 @@ fn hex_dir_parser(input: &str) -> IResult<&str, Vector2<i32>> {
}
impl FloodFillMap {
- fn new(map: HashMap<Point2<i32>, Fill>) -> FloodFillMap {
+ fn new(map: HashMap<Point2<i64>, Fill>) -> FloodFillMap {
let top_left = Point2::new(
map.keys().map(|key| key.x).min().unwrap() - 1,
map.keys().map(|key| key.y).min().unwrap() - 1,
@@ -166,7 +193,7 @@ impl FloodFillMap {
.count()
}
- fn flood_fill(&mut self, start: Point2<i32>, fill: &Fill) {
+ fn flood_fill(&mut self, start: Point2<i64>, fill: &Fill) {
let mut to_fill = vec![start];
while let Some(next) = to_fill.pop() {