-
Notifications
You must be signed in to change notification settings - Fork 0
/
day13.ts
73 lines (53 loc) · 1.78 KB
/
day13.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import input from './resources/day13_input.txt' with { type: 'text' };
type Coordinates = { x: number; y: number };
type Group = {
buttonA: Coordinates;
buttonB: Coordinates;
prize: Coordinates;
};
const parseInput = (input: string): Group[] =>
input
.trim()
.split('\n\n')
.map((group) => {
const matches = group.matchAll(/X[+](\d+), Y[+](\d+)|X=(\d+), Y=(\d+)/g);
const parseCoords = (match: RegExpMatchArray): Coordinates => {
const x = parseInt(match[1] || match[3], 10);
const y = parseInt(match[2] || match[4], 10);
return { x, y };
};
const [buttonA, buttonB, prize] = Array.from(matches, parseCoords);
return { buttonA, buttonB, prize };
});
const groups = parseInput(input);
type Solution = { nA: number; nB: number } | null;
const solveLinear = (
xA: number, yA: number,
xB: number, yB: number,
xTarget: number, yTarget: number
): Solution => {
const det = xA * yB - xB * yA;
if (det === 0) {
return null;
}
const nA_base = (yB * xTarget - xB * yTarget) / det;
const nB_base = (xA * yTarget - yA * xTarget) / det;
if (!Number.isInteger(nA_base) || !Number.isInteger(nB_base)) {
return null;
}
let nA = Math.round(nA_base);
let nB = Math.round(nB_base);
if (nA < 0 || nB < 0) {
return null;
}
return { nA, nB };
}
const solve = (
xA: number, yA: number,
xB: number, yB: number,
xTarget: number, yTarget: number): Solution => {
return solveLinear(xA, yA, xB, yB, xTarget + 10000000000000, yTarget + 10000000000000);
}
const cost = (solution: Solution): number => 3 * solution!.nA + solution!.nB;
const result = groups.map(({ buttonA, buttonB, prize }) => solve(buttonA.x, buttonA.y, buttonB.x, buttonB.y, prize.x, prize.y)).filter((solution) => solution !== null).map(cost).reduce((a, b) => a + b, 0);
console.log('cost', result);