-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(js): add solutions for 2024 day 14
- Loading branch information
1 parent
44fdcf3
commit cb18470
Showing
2 changed files
with
93 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* eslint-disable no-loop-func */ | ||
|
||
import { mod, multiply, solution } from '../../utils/index.js'; | ||
|
||
const SIGNED_NUMBER_MATCHER = /-?\d+/g; | ||
|
||
const parse = (input) => | ||
input | ||
.trim() | ||
.split('\n') | ||
.map((line) => { | ||
const [px, py, dx, dy] = Array.from(line.matchAll(SIGNED_NUMBER_MATCHER)).map((match) => | ||
Number(match[0]), | ||
); | ||
return { px, py, dx, dy }; | ||
}); | ||
|
||
const predict = (robot, steps, width, height) => { | ||
const px = mod(robot.px + steps * robot.dx, width); | ||
const py = mod(robot.py + steps * robot.dy, height); | ||
return { px, py }; | ||
}; | ||
|
||
// Whether given robot is within radial distance 1 of other robot | ||
const isNearOther = (robot, other) => { | ||
const diffx = Math.abs(robot.px - other.px); | ||
const diffy = Math.abs(robot.py - other.py); | ||
return robot !== other && diffx <= 1 && diffy <= 1; | ||
}; | ||
|
||
// Whether this configuration of robots visually contains a hidden Christmas tree (!) | ||
// Note: uses an arbitrary cluster threshold, as Erik sneakily decided to not let _all_ robots contribute | ||
const isChristmasTree = (robots, threshold = 0.75) => { | ||
const total = robots.length; | ||
const clustered = robots.reduce((sum, robot) => sum + robots.some((other) => isNearOther(robot, other)), 0); | ||
const percent = clustered / total; | ||
return percent >= threshold; | ||
}; | ||
|
||
export const partOne = solution((input, { width = 101, height = 103 }) => { | ||
const robots = parse(input); | ||
|
||
const middlex = (width / 2) | 0; | ||
const middley = (height / 2) | 0; | ||
|
||
const steps = 100; | ||
|
||
const quadrants = [0, 0, 0, 0]; | ||
|
||
for (const robot of robots) { | ||
const { px, py } = predict(robot, steps, width, height); | ||
const inMiddle = px === middlex || py === middley; | ||
if (!inMiddle) { | ||
const index = ((((py - 1) / middley) | 0) << 1) | (((px - 1) / middlex) | 0); | ||
quadrants[index]++; | ||
} | ||
} | ||
|
||
return multiply(quadrants); | ||
}); | ||
|
||
export const partTwo = solution.inefficient((input, { width = 101, height = 103 }) => { | ||
const robots = parse(input); | ||
|
||
let steps = 1; | ||
while (true) { | ||
const snapshot = robots.map((robot) => predict(robot, steps, width, height)); | ||
if (isChristmasTree(snapshot)) { | ||
break; | ||
} | ||
++steps; | ||
} | ||
|
||
return steps; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
part-one: | ||
- input: | | ||
p=0,4 v=3,-3 | ||
p=6,3 v=-1,-3 | ||
p=10,3 v=-1,2 | ||
p=2,0 v=2,-1 | ||
p=0,0 v=1,3 | ||
p=3,0 v=-2,-2 | ||
p=7,6 v=-1,-3 | ||
p=3,0 v=-1,-2 | ||
p=9,3 v=2,3 | ||
p=7,3 v=-1,2 | ||
p=2,4 v=2,-3 | ||
p=9,5 v=-3,-3 | ||
answer: 12 | ||
args: | ||
width: 11 | ||
height: 7 |