[TASK] Cleaned up (and improved the performance a little) for day 17
This commit is contained in:
@@ -53,22 +53,24 @@ class Day17 implements Day {
|
||||
|
||||
part2(input: string[]): number | string {
|
||||
|
||||
// So that means that the only y values that work are those for which two triangle numbers exists, between which the distance falls
|
||||
// in the target area.
|
||||
// Following this reasoning, we also know that y is inside the target area after (2 * v_y0) + { the number of triangle numbers between triangle(vy_0) and triangle(?) in y_range) }
|
||||
|
||||
const targetArea = TargetArea.parse(input[0]);
|
||||
|
||||
const v_x0_min = Day17.triangleInvCeil(targetArea.minX);
|
||||
const v_x0_max_static = Day17.triangleInvFloor(targetArea.maxX);
|
||||
// const maxYSteps0 = Day17.triangleInvCeil(Math.abs(targetArea.minY));
|
||||
const maxYStepsBelowZero = Day17.triangleInvCeil(Math.abs(targetArea.minY));
|
||||
|
||||
let solutionCount = 0;
|
||||
|
||||
for (let v_x0 = v_x0_min; v_x0 <= targetArea.maxX; v_x0++) {
|
||||
const maxSteps = v_x0 <= v_x0_max_static ? 1000 : v_x0_max_static;
|
||||
for (let v_y0 = targetArea.minY; v_y0 < Math.abs(targetArea.minY); v_y0++) {
|
||||
for (let steps = 1; steps < maxSteps; steps++) {
|
||||
|
||||
// If v_x0 <= v_x0_max_static, we end up in a position where eventually all x-es fall in the valid range
|
||||
// So in that case, we base the max steps on the y values.
|
||||
const maxSteps = v_x0 <= v_x0_max_static
|
||||
? (v_y0 < 0 ? maxYStepsBelowZero : 2 * v_y0 + 1 + maxYStepsBelowZero)
|
||||
: v_x0_max_static;
|
||||
|
||||
for (let steps = 1; steps <= maxSteps; steps++) {
|
||||
const xRangeResult = this.isInXAfterSteps(v_x0, steps, targetArea);
|
||||
if (xRangeResult === RangeResult.TOO_HIGH) {
|
||||
break;
|
||||
@@ -86,55 +88,6 @@ class Day17 implements Day {
|
||||
}
|
||||
return solutionCount;
|
||||
|
||||
// // We gonna have to semi-brute-force anyway,
|
||||
//
|
||||
// // But first, let's find all x-es that perpetually stay inside the target area
|
||||
// const v_x0_min = Day17.triangleInvCeil(targetArea.minX);
|
||||
// const v_x0_max_static = Day17.triangleInvFloor(targetArea.maxX);
|
||||
//
|
||||
// // const vxStaticCount = (v_x0_max_static - v_x0_min) + 1;
|
||||
// //
|
||||
// // Then we count all y's that end up in the target area after v_x0_min steps
|
||||
// // Note that any
|
||||
// // if (v_x0_min * 2 + 1 > Math.abs(targetArea.maxY) + 1);
|
||||
// let vyStaticCount = 0;
|
||||
// // With a start y speed of 0, we can stay in the target area for at most this many steps:
|
||||
// const maxYSteps0 = Day17.triangleInvCeil(Math.abs(targetArea.minY));
|
||||
//
|
||||
// for (let vy_0 = targetArea.minY; vy_0 < Math.abs(targetArea.minY); vy_0++) {
|
||||
// const minSteps = vy_0 > 0 ? Math.max(v_x0_min, 2 * vy_0 + 1) : v_x0_min;
|
||||
// const maxSteps = vy_0 > 0 ? minSteps + maxYSteps0 : maxYSteps0;
|
||||
// for (let steps = minSteps; steps < maxSteps; steps++) {
|
||||
// const rangeResult = this.isInYAfterSteps(vy_0, steps, targetArea);
|
||||
// if (rangeResult === RangeResult.YES) {
|
||||
// vyStaticCount++;
|
||||
// break;
|
||||
// } else if (rangeResult === RangeResult.TOO_LOW) {
|
||||
// // We've fallen below the target area, no need to scan this range any further
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// const staticSolutions = (v_x0_max_static - v_x0_min + 1) * vyStaticCount;
|
||||
//
|
||||
// // Any more numbers of steps will overshoot the x direction
|
||||
// let dynamicSolutions = 0;
|
||||
// for (let steps = 1; steps <= v_x0_max_static; steps++) {
|
||||
// for (let vx_0 = v_x0_min; vx_0 < targetArea.maxX + 1; vx_0++) {
|
||||
// if (this.isInXAfterSteps(vx_0, steps, targetArea) !== RangeResult.YES) continue;
|
||||
// for (let vy_0 = targetArea.minY; vy_0 < Math.abs(targetArea.minY) - 1; vy_0++) {
|
||||
// const rangeResult = this.isInYAfterSteps(vy_0, steps, targetArea);
|
||||
// if (rangeResult === RangeResult.YES) {
|
||||
// dynamicSolutions++;
|
||||
// } else if (rangeResult === RangeResult.TOO_HIGH) {
|
||||
// // We've fallen below the target area
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return dynamicSolutions + staticSolutions;
|
||||
}
|
||||
|
||||
isInXAfterSteps(v_x0: number, steps: number, targetArea: TargetArea): RangeResult {
|
||||
@@ -241,82 +194,6 @@ class TargetArea {
|
||||
else if (y > this.maxY) return RangeResult.TOO_HIGH;
|
||||
else return RangeResult.YES;
|
||||
}
|
||||
|
||||
isIn(x: number, y: number): boolean {
|
||||
return this.isInX(x) === RangeResult.YES && this.isInY(y) === RangeResult.YES;
|
||||
}
|
||||
}
|
||||
|
||||
export default Day17;
|
||||
|
||||
const exampleInput = ["target area: x=20..30, y=-10..-5"];
|
||||
run(exampleInput);
|
||||
|
||||
const input = ["target area: x=48..70, y=-189..-148"];
|
||||
run(input);
|
||||
|
||||
|
||||
function run(input: string[]) {
|
||||
const day = new Day17();
|
||||
console.log(`Part 1: ${day.part1(input)}`);
|
||||
console.log(`Part 2: ${day.part2(input)}`);
|
||||
}
|
||||
|
||||
|
||||
// Archive:
|
||||
|
||||
// const maxYs: number[] = [];
|
||||
// const yMinStepInTargets = [];
|
||||
// const yMaxStepInTargets = [];
|
||||
// // Array(100).fill([]);
|
||||
// // Let's first find the y values that reach the highest height and end up in the target area:
|
||||
// for (let vy0 = 0; vy0 < Math.abs(targetArea.minY) + 1; vy0++) {
|
||||
//
|
||||
// let y = 0;
|
||||
// const ys = [y];
|
||||
// let vy = vy0;
|
||||
// let yMinStepInTarget = -1;
|
||||
// let yMaxStepInTarget = -1;
|
||||
// let step = 0;
|
||||
// while (y > targetArea.minY) {
|
||||
// y += vy;
|
||||
// ys.push(y);
|
||||
// vy--;
|
||||
// if (targetArea.isInY(y)) {
|
||||
// if (yMinStepInTarget === -1) {
|
||||
// yMinStepInTarget = step;
|
||||
// }
|
||||
// yMaxStepInTarget = step;
|
||||
// }
|
||||
// step++;
|
||||
// }
|
||||
// yMinStepInTargets.push(yMinStepInTarget)
|
||||
// yMaxStepInTargets.push(yMaxStepInTarget)
|
||||
// // yCache.push(ys);
|
||||
// maxYs.push(Math.max(...ys));
|
||||
// }
|
||||
//
|
||||
// // Now we "greedily" go over the found y values
|
||||
//
|
||||
// // First we find all x-es between 1 and maxX + 1 (as all others will immediately overshoot), that overlap with the target at some points:
|
||||
// for (let x = 1; x <= targetArea.maxX + 1; x++) {
|
||||
// let curSpeed = x;
|
||||
// let curPosX = 0;
|
||||
// for (let step = 0; step < (targetArea.maxX + 1) / x; step++) {
|
||||
//
|
||||
// curPosX += curSpeed;
|
||||
// if (targetArea.isInX(curPosX)) {
|
||||
// // Find y's that given this position and step, match:
|
||||
// // TODO: find out which y's make sense to check
|
||||
// for (let y = 0; y < 100; y++) {
|
||||
//
|
||||
//
|
||||
// // f(s) = s * y +
|
||||
// }
|
||||
// const { maxY, finalY } = this.simulateY()
|
||||
// } else if ( curPosX > targetArea.maxX || (curSpeed === 0 && curPosX < targetArea.minX)) {
|
||||
// break;
|
||||
// }
|
||||
// curSpeed--;
|
||||
// }
|
||||
// }
|
||||
|
||||
6
input/day/17-example.http
Normal file
6
input/day/17-example.http
Normal file
@@ -0,0 +1,6 @@
|
||||
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-17
|
||||
Content-Type: text/plain
|
||||
|
||||
target area: x=20..30, y=-10..-5
|
||||
|
||||
###
|
||||
6
input/day/17.http
Normal file
6
input/day/17.http
Normal file
@@ -0,0 +1,6 @@
|
||||
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-17
|
||||
Content-Type: text/plain
|
||||
|
||||
target area: x=48..70, y=-189..-148
|
||||
|
||||
###
|
||||
Reference in New Issue
Block a user