[TASK] Cleaned up (and improved the performance a little) for day 17

This commit is contained in:
2021-12-19 14:53:25 +01:00
parent 9fc38b9b88
commit 5d54a107d4
3 changed files with 21 additions and 132 deletions

View File

@@ -53,22 +53,24 @@ class Day17 implements Day {
part2(input: string[]): number | string { 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 targetArea = TargetArea.parse(input[0]);
const v_x0_min = Day17.triangleInvCeil(targetArea.minX); const v_x0_min = Day17.triangleInvCeil(targetArea.minX);
const v_x0_max_static = Day17.triangleInvFloor(targetArea.maxX); 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; let solutionCount = 0;
for (let v_x0 = v_x0_min; v_x0 <= targetArea.maxX; v_x0++) { 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 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); const xRangeResult = this.isInXAfterSteps(v_x0, steps, targetArea);
if (xRangeResult === RangeResult.TOO_HIGH) { if (xRangeResult === RangeResult.TOO_HIGH) {
break; break;
@@ -86,55 +88,6 @@ class Day17 implements Day {
} }
return solutionCount; 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 { 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 if (y > this.maxY) return RangeResult.TOO_HIGH;
else return RangeResult.YES; else return RangeResult.YES;
} }
isIn(x: number, y: number): boolean {
return this.isInX(x) === RangeResult.YES && this.isInY(y) === RangeResult.YES;
}
} }
export default Day17; 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--;
// }
// }

View 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
View 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
###