Skip to content

Commit

Permalink
2023 day 10 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
H-Rusch committed Dec 10, 2023
1 parent 0c5b668 commit 01582a3
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 13 deletions.
9 changes: 9 additions & 0 deletions aoc23/examples/day10_2_1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
...........
.S-------7.
.|F-----7|.
.||.....||.
.||.....||.
.|L-7.F-J|.
.|..|.|..|.
.L--J.L--J.
...........
10 changes: 10 additions & 0 deletions aoc23/examples/day10_2_2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.F----7F7F7F7F-7....
.|F--7||||||||FJ....
.||.FJ||||||||L7....
FJL7L7LJLJ||LJ.L-7..
L--J.L7...LJS7F-7L7.
....F-J..F7FJ|L7L7L7
....L7.F7||L7|.L7L7|
.....|FJLJ|FJ|F7|.LJ
....FJL-7.||.||||...
....L---J.LJ.LJLJ...
10 changes: 10 additions & 0 deletions aoc23/examples/day10_2_3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FF7FSF7F7F7F7F7F---7
L|LJ||||||||||||F--J
FL-7LJLJ||||||LJL-77
F--JF--7||LJLJ7F7FJ-
L---JF-JLJ.||-FJLJJ7
|F|F-JF---7F7-L7L|7|
|FFJF7L7F-JF7|JL---7
7-L-JL7||F7|L7F-7F7|
L.L7LFJ|||||FJL7||LJ
L7JLJL-JLJLJL--JLJ.L
59 changes: 46 additions & 13 deletions aoc23/src/solutions/day10.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,26 @@ pub fn part1(input: &str) -> usize {
}

pub fn part2(input: &str) -> usize {
0
let (coordinates, start) = parse(input);
let circle = find_circle(start, &coordinates);

enclosed_area(&circle)
}

fn find_circle(start: Coordinate, coordinates: &HashMap<Coordinate, char>) -> String {
fn find_circle(start: Coordinate, coordinates: &HashMap<Coordinate, char>) -> Vec<Coordinate> {
let mut queue = init_queue(&start, coordinates);

while let Some((coordinate, direction, path)) = queue.pop_front() {
while let Some((coordinate, direction, mut path)) = queue.pop_front() {
if coordinate == start {
return path;
}

let pipe = coordinates.get(&coordinate).unwrap();
let next_direction = next_direction(*pipe, direction);
let next_coordinate = coordinate.step(&next_direction, 1);
let mut next_path = path.clone();
next_path.push(*pipe);
path.push(next_coordinate);

queue.push_back((next_coordinate, next_direction, next_path));
queue.push_back((next_coordinate, next_direction, path));
}

unreachable!()
Expand All @@ -36,7 +38,7 @@ fn find_circle(start: Coordinate, coordinates: &HashMap<Coordinate, char>) -> St
fn init_queue(
start: &Coordinate,
coordinates: &HashMap<Coordinate, char>,
) -> VecDeque<(Coordinate, Direction, String)> {
) -> VecDeque<(Coordinate, Direction, Vec<Coordinate>)> {
[
Direction::Up,
Direction::Left,
Expand All @@ -49,7 +51,7 @@ fn init_queue(
coordinates.contains_key(coordinate)
&& valid_directions(*coordinates.get(coordinate).unwrap(), direction)
})
.map(|(coordinate, direction)| (coordinate, direction, String::from("S")))
.map(|(coordinate, direction)| (coordinate, direction, vec![coordinate]))
.collect()
}

Expand Down Expand Up @@ -84,6 +86,32 @@ fn valid_directions(pipe: char, direction: &Direction) -> bool {
)
}

fn enclosed_area(circle: &[Coordinate]) -> usize {
let area = shoelace(circle);
internal_points(circle, area)
}

fn shoelace(polygon: &[Coordinate]) -> usize {
// Use the shoelace formula (https://en.wikipedia.org/wiki/Shoelace_formula) to calculate the area of the polygon.

let mut polygon: Vec<Coordinate> = polygon.to_vec();
polygon.push(polygon[0]);

let area: i32 = polygon
.iter()
.zip(polygon.iter().skip(1))
.map(|(p1, p2)| (p1.x * p2.y) - (p1.y * p2.x))
.sum();

area.unsigned_abs() as usize / 2
}

fn internal_points(polygon: &[Coordinate], area: usize) -> usize {
// Calculate number of inside points of the polygon defined though the coordinates with the Pick's Theorem (https://en.wikipedia.org/wiki/Pick%27s_theorem).

area - polygon.len() / 2 + 1
}

fn parse(input: &str) -> (HashMap<Coordinate, char>, Coordinate) {
let mut coordinates = HashMap::new();
for (y, row) in input.lines().enumerate() {
Expand Down Expand Up @@ -114,17 +142,22 @@ fn find_start(input: &str) -> Coordinate {
mod tests {
use super::*;

const EXAMPLE_1: &str = include_str!("../../examples/day10_1_1.txt");
const EXAMPLE_2: &str = include_str!("../../examples/day10_1_2.txt");
const EXAMPLE_1_1: &str = include_str!("../../examples/day10_1_1.txt");
const EXAMPLE_1_2: &str = include_str!("../../examples/day10_1_2.txt");
const EXAMPLE_2_1: &str = include_str!("../../examples/day10_2_1.txt");
const EXAMPLE_2_2: &str = include_str!("../../examples/day10_2_2.txt");
const EXAMPLE_2_3: &str = include_str!("../../examples/day10_2_3.txt");

#[test]
fn part1_ex() {
assert_eq!(4, part1(EXAMPLE_1));
assert_eq!(8, part1(EXAMPLE_2));
assert_eq!(4, part1(EXAMPLE_1_1));
assert_eq!(8, part1(EXAMPLE_1_2));
}

#[test]
fn part2_ex() {
assert_eq!(0, part2(""));
assert_eq!(4, part2(EXAMPLE_2_1));
assert_eq!(8, part2(EXAMPLE_2_2));
assert_eq!(10, part2(EXAMPLE_2_3));
}
}

0 comments on commit 01582a3

Please sign in to comment.