Skip to content

Commit

Permalink
feat(js): add solutions for 2023 day 10
Browse files Browse the repository at this point in the history
  • Loading branch information
timkurvers committed Dec 10, 2023
1 parent 1a7b6b6 commit cb744b2
Show file tree
Hide file tree
Showing 3 changed files with 326 additions and 0 deletions.
119 changes: 119 additions & 0 deletions js/src/2023/10/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/* eslint-disable consistent-return, quote-props */

import { Grid, Orientation, dx, dy, solution } from '../../utils';

const PIPES = {
'|': { // vertical pipe connecting north and south.
[Orientation.UP]: Orientation.UP,
[Orientation.DOWN]: Orientation.DOWN,
},
'-': { // horizontal pipe connecting east and west.
[Orientation.LEFT]: Orientation.LEFT,
[Orientation.RIGHT]: Orientation.RIGHT,
},
'L': { // 90-degree bend connecting north and east.
[Orientation.DOWN]: Orientation.RIGHT,
[Orientation.LEFT]: Orientation.UP,
},
'J': { // 90-degree bend connecting north and west.
[Orientation.DOWN]: Orientation.LEFT,
[Orientation.RIGHT]: Orientation.UP,
},
'7': { // 90-degree bend connecting south and west.
[Orientation.UP]: Orientation.LEFT,
[Orientation.RIGHT]: Orientation.DOWN,
},
'F': { // 90-degree bend connecting south and east.
[Orientation.UP]: Orientation.RIGHT,
[Orientation.LEFT]: Orientation.DOWN,
},
};

const parse = (input) => Grid.from(input.trim());

const traverse = (grid, start) => {
// Does not matter which orientation to start with (as it is a loop)
let orientation = Object.values(PIPES[start.value])[0];

let current = start;
const path = [];
do {
const next = grid.getPoint(current.x + dx(orientation), current.y + dy(orientation));
const directions = PIPES[next?.value];
if (!directions || !(orientation in directions)) {
return null;
}
orientation = directions[orientation];
path.push(next);
current = next;
} while (current !== start);
return path;
};

const findLoop = (grid) => {
const start = grid.find((point) => point.value === 'S');

// What's that? Brute-force again? Yes.
for (const variant of Object.keys(PIPES)) {
start.value = variant;
const path = traverse(grid, start);
if (path) {
return path;
}
}
};

export const partOne = solution((input) => {
const grid = parse(input);
const loop = findLoop(grid);
return loop.length / 2;
});

export const partTwo = solution((input) => {
const grid = parse(input);
const loop = findLoop(grid);

let area = 0;

// See: https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm
let y = 0;
let enclosed = false;
let edge = null;
for (const point of grid) {
if (point.y > y) {
enclosed = false;
edge = null;
y = point.y;
}

const onLoop = loop.includes(point);

const { value } = point;
if (onLoop && value !== '-') {
// Sweet jesus, this took way too long to figure out :')

// When dealing with a boxed edge: ┌─┐ or └─┘
if ((edge === 'F' && value === '7') || (edge === 'L' && value === 'J')) {
enclosed = !enclosed;
edge = null;

// When dealing with a bend: ┌─┘ or └─┐
} else if ((edge === 'F' && value === 'J') || (edge === 'L' && value === '7')) {
edge = null;

// Mark as intersection for all other cases and handle edge entry: ┌─ or └─
} else {
enclosed = !enclosed;
if (value === 'F' || value === 'L') {
edge = value;
}
}
}

if (!onLoop && enclosed) {
++area;
}
}

return area;
});
67 changes: 67 additions & 0 deletions puzzles/2023/10/examples.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
part-one:
- input: |
.....
.S-7.
.|.|.
.L-J.
.....
answer: 4
- input: |
..F7.
.FJ|.
SJ.L7
|F--J
LJ...
answer: 8
part-two:
- input: |
...........
.S-------7.
.|F-----7|.
.||.....||.
.||.....||.
.|L-7.F-J|.
.|..|.|..|.
.L--J.L--J.
...........
answer: 4
- input: |
..........
.S------7.
.|F----7|.
.||OOOO||.
.||OOOO||.
.|L-7F-J|.
.|II||II|.
.L--JL--J.
..........
answer: 4
- input: |
.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...
answer: 8
- input: |
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
answer: 10
Loading

0 comments on commit cb744b2

Please sign in to comment.