-
Notifications
You must be signed in to change notification settings - Fork 1
/
17.js
105 lines (98 loc) · 2.38 KB
/
17.js
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
'use strict';
/**
* @param {string} d
*/
export const part1 = async d => {
const [, xMin, xMax, yMax, yMin] = /x=(-?\d+)\.\.(-?\d+), y=(-?\d+)\.\.(-?\d+)/.exec(d).map(e => parseInt(e, 10));
const step = (pos, vel) => {
pos[0] += vel[0];
pos[1] += vel[1];
if (vel[0] > 0) {
vel[0]--;
}
if (vel[0] < 0) {
vel[0]++;
}
vel[1]--;
};
// Find x velocities that will land in the target
const xVelMax = xMax + 1;
const validXVel = new Set;
for (let xVel = 1; xVel < xVelMax; xVel++) {
const pos = [0, 0];
const vel = [xVel, 0]; // Don't care about the y yet
while (vel[0] > 0 && pos[0] <= xMax) {
step(pos, vel);
if (pos[0] >= xMin && pos[0] <= xMax) {
validXVel.add(xVel);
}
}
}
// Now to find xy velcity that gives us the
let yPosMax = 0;
validXVel.forEach(xVel => {
for (let yVel = 0; yVel < 5000; yVel++) {
const pos = [0, 0];
const vel = [xVel, yVel];
let yPosCurMax = 0;
let hitTarget = false;
while (pos[0] <= xMax && pos[1] >= yMax) {
step(pos, vel);
yPosCurMax = Math.max(yPosCurMax, pos[1]);
if (pos[0] >= xMin && pos[1] >= yMax && pos[0] <= xMax && pos[1] <= yMin) {
hitTarget = true;
}
}
if (hitTarget) {
yPosMax = Math.max(yPosMax, yPosCurMax);
}
}
});
return yPosMax;
};
/**
* @param {string} d
*/
export const part2 = async d => {
const [, xMin, xMax, yMax, yMin] = /x=(-?\d+)\.\.(-?\d+), y=(-?\d+)\.\.(-?\d+)/.exec(d).map(e => parseInt(e, 10));
const step = (pos, vel) => {
pos[0] += vel[0];
pos[1] += vel[1];
if (vel[0] > 0) {
vel[0]--;
}
if (vel[0] < 0) {
vel[0]++;
}
vel[1]--;
};
const validVel = [];
// Find x velocities that will land in the target
const xVelMax = xMax + 1;
const validXVel = new Set;
for (let xVel = 1; xVel < xVelMax; xVel++) {
const pos = [0, 0];
const vel = [xVel, 0]; // Don't care about the y yet
while (vel[0] > 0 && pos[0] <= xMax) {
step(pos, vel);
if (pos[0] >= xMin && pos[0] <= xMax) {
validXVel.add(xVel);
}
}
}
// Now to find xy velcity that hits the target
validXVel.forEach(xVel => {
for (let yVel = yMax; yVel < 5000; yVel++) {
const pos = [0, 0];
const vel = [xVel, yVel];
while (pos[0] <= xMax && pos[1] >= yMax) {
step(pos, vel);
if (pos[0] >= xMin && pos[1] >= yMax && pos[0] <= xMax && pos[1] <= yMin) {
validVel.push([xVel, yVel]);
break;
}
}
}
});
return validVel.length;
};