Skip to content

Instantly share code, notes, and snippets.

@p-a
Last active December 21, 2022 12:03
AoC 2022 Day 19
const RE = /Blueprint (\d+): Each ore robot costs (\d+) ore. Each clay robot costs (\d+) ore. Each obsidian robot costs (\d+) ore and (\d+) clay. Each geode robot costs (\d+) ore and (\d+) obsidian./;
const parse = input =>
input
.split("\n")
.map(line => RE.exec(line))
.map(([, ...num]) => num.map(Number))
.map(
([
,
ore,
clay,
obs_ore,
obs_clay,
geode_ore,
geode_obs,
]) => [
[ore, 0, 0, 0],
[clay, 0, 0, 0],
[obs_ore, obs_clay, 0, 0],
[geode_ore, 0, geode_obs, 0],
]
);
const [ORE, CLAY, OBSIDIAN, GEODE] = [0, 1, 2, 3];
const harvest = (costs, minutes) => {
const score = (time, [material, robots]) =>
((material[GEODE] + (minutes - time) * robots[GEODE]) <<
16) +
(robots[OBSIDIAN] << 8) +
(robots[CLAY] << 4) +
robots[ORE];
let prioq = [
[
[0, 0, 0, 0],
[1, 0, 0, 0],
],
];
const maxBotsNeeded = [ORE, CLAY, OBSIDIAN]
.map(r =>
costs
.map(cost => cost[r])
.reduce((max, v) => (max > v ? max : v))
)
.concat(Infinity);
let time = 0;
while (time++ < minutes) {
prioq = prioq
.flatMap(([resources, robots]) =>
[GEODE, OBSIDIAN, CLAY, ORE]
.filter(
type =>
maxBotsNeeded[type] > robots[type] &&
resources.every((m, i) => m >= costs[type][i])
)
.map(type => [
resources.map(
(amount, i) =>
amount + robots[i] - costs[type][i]
),
robots.map((r, i) => r + (i === type ? 1 : 0)),
])
.concat([
[
resources.map(
(amount, i) => amount + robots[i]
),
robots,
],
])
.map(s => [...s, score(time, s)])
)
.sort(([, , a], [, , b]) => b - a)
.slice(0, 5000);
}
return prioq[0][0][GEODE];
};
export const part1 = input =>
parse(input)
.map((bp, i) => [harvest(bp, 24), i + 1])
.map(([a, b]) => a * b)
.reduce((sum, v) => sum + v);
export const part2 = input =>
parse(input)
.slice(0, 3)
.map(bp => harvest(bp, 32))
.reduce((p, v) => p * v);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment