diff --git a/functions/src/day17.ts b/functions/src/day17.ts new file mode 100644 index 0000000..96d0548 --- /dev/null +++ b/functions/src/day17.ts @@ -0,0 +1,123 @@ +import Day from "./day"; + +class Day17 implements Day { + + part1(input: string[]): number | string { + + const targetArea = TargetArea.parse(input[0]); + + // 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++) { + // steps = 3 + // y = 1 -> 1 + 0 + -1 = 0 + // y = 2 -> 2 + 1 + 0 = 3 + // y = 3 -> 3 + 2 + 1 = 6 + // y = 4 -> 4 + 3 + 2 = 9 + // y = 5 -> 5 + 4 + 3 = 12 + + // steps = 4 + // y = 1 -> -2 + // y = 2 -> 2 + // y = 3 -> 6 + // y = 4 -> 10 + + // y = 0 + // steps = 1 -> 0 = 0 + // steps = 2 -> 0 - 1 = -1 + // steps = 3 -> 0 - 1 - 2 = -3 + // steps = 4 -> 0 - 1- 2 - 3= -6 + // steps = 5 -> 0-1-2-3-4 = -10 + // steps = 6 -> 0-1-2-3-4-5 = -15 + + // v = -1 * x + // pos = -.5 * steps^2 + y * steps + + // f(s) = s * y + + } + const { maxY, finalY } = this.simulateY() + } else if ( curPosX > targetArea.maxX || (curSpeed === 0 && curPosX < targetArea.minX)) { + break; + } + curSpeed--; + } + } + + return 0; + } + + simulateY(initialSpeedY: number, steps: number): { maxY: number, finalY: number} { + + let curSpeed = initialSpeedY; + let y = 0; + let maxY = 0; + for (let step = 0; step < steps; step++) { + y += curSpeed; + curSpeed--; + if (y > maxY) { + maxY = y; + } + } + return { finalY: y, maxY: maxY }; + } + + part2(input: string[]): number | string { + // TODO implement + return 0; + } + +} + +class TargetArea { + + minX: number; + maxX: number; + minY: number; + maxY: number; + + + constructor(minX: number, maxX: number, minY: number, maxY: number) { + this.minX = minX; + this.maxX = maxX; + this.minY = minY; + this.maxY = maxY; + } + + static parse(input: string): TargetArea { + const regex = /^target area: x=(-?[0-9]+)\.\.(-?[0-9]+), y=(-?[0-9]+)..(-?[0-9]+)$/i; + const match = input.trim().match(regex); + + if (!match || match.length < 5) { + throw Error("Invalid input: '" + input + "'"); + } + + return new TargetArea( + parseInt(match[1]), + parseInt(match[2]), + parseInt(match[3]), + parseInt(match[4]), + ) + } + + isInX(x: number): boolean { + return x >= this.minX && x <= this.maxX; + } + + isInY(y: number): boolean { + return y >= this.minY && y <= this.maxY; + } + + isIn(x: number, y: number): boolean { + return this.isInX(x) && this.isInY(y); + } +} + +export default Day17; diff --git a/functions/src/index.ts b/functions/src/index.ts index ea0b90b..5b4ea3d 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -18,6 +18,7 @@ import Day13 from "./day13"; import Day14 from "./day14"; import Day15 from "./day15"; import Day16 from "./day16"; +import Day17 from './day17'; // // Start writing Firebase Functions @@ -50,6 +51,7 @@ export const day = { 14: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day14(), request, response) }), 15: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day15(), request, response) }), 16: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day16(), request, response) }), + 17: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day17(), request, response) }), }