From 875e5c1680137ca093c47828f108601293ee66ba Mon Sep 17 00:00:00 2001 From: Pascal Syma Date: Wed, 10 Dec 2025 13:40:27 +0100 Subject: [PATCH] Solve 2025-09 --- 2025/09/2025-09.run.xml | 7 ++++ 2025/09/index.test.ts | 19 ++++++++++ 2025/09/index.ts | 78 +++++++++++++++++++++++++++++++++++++++++ 2025/09/run.ts | 12 +++++++ 4 files changed, 116 insertions(+) create mode 100644 2025/09/2025-09.run.xml create mode 100644 2025/09/index.test.ts create mode 100644 2025/09/index.ts create mode 100644 2025/09/run.ts diff --git a/2025/09/2025-09.run.xml b/2025/09/2025-09.run.xml new file mode 100644 index 0000000..13b3bc2 --- /dev/null +++ b/2025/09/2025-09.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/2025/09/index.test.ts b/2025/09/index.test.ts new file mode 100644 index 0000000..25f40c3 --- /dev/null +++ b/2025/09/index.test.ts @@ -0,0 +1,19 @@ +import { describe, expect, it } from 'bun:test'; +import { solveFirst, solveSecond } from './index.ts'; + +describe('2025-09', () => { + const testInput = `7,1 +11,1 +11,7 +9,7 +9,5 +2,5 +2,3 +7,3`; + it('first', () => { + expect(solveFirst(testInput)).toBe(50); + }); + it('second', () => { + expect(solveSecond(testInput)).toBe(25); + }); +}); diff --git a/2025/09/index.ts b/2025/09/index.ts new file mode 100644 index 0000000..df50126 --- /dev/null +++ b/2025/09/index.ts @@ -0,0 +1,78 @@ +import { uniqueCombinations } from '../../utils/array.ts'; +import type { Coordinate } from '../../utils/coordinates.ts'; + +export function solveFirst(input: string): number { + const reds = input + .split('\n') + .map((r) => r.split(',').map(Number) as Coordinate); + + const combs = uniqueCombinations(reds) + .map( + ({ a, b }) => (Math.abs(a[0] - b[0]) + 1) * (Math.abs(a[1] - b[1]) + 1) + ) + .toSorted((a, b) => b - a); + return combs[0]; +} + +function calcArea(a: Coordinate, b: Coordinate) { + return (Math.abs(a[0] - b[0]) + 1) * (Math.abs(a[1] - b[1]) + 1); +} + +export function solveSecond(input: string): number { + const reds = input + .split('\n') + .map((r) => r.split(',').map(Number) as Coordinate); + + const lines: Line[] = []; + for (let i = 1; i < reds.length; i++) { + lines.push([reds[i - 1], reds[i]]); + } + lines.push([reds[reds.length - 1], reds[0]]); + + let maxArea = 0; + + for (let i = 0; i < reds.length; i++) { + for (let j = i + 1; j < reds.length; j++) { + if (reds[i][0] == reds[j][0] || reds[i][1] == reds[j][1]) continue; + const rectLines: Line[] = [ + [reds[i], reds[j]], + [ + [reds[i][0], reds[j][1]], + [reds[j][0], reds[i][1]] + ] + ]; + + if ( + rectLines.some((rline) => lines.some((line) => intersects(rline, line))) + ) { + continue; + } + + maxArea = Math.max(maxArea, calcArea(reds[i], reds[j])); + } + } + + return maxArea; +} + +/** + * Checks for intersection of two lines. + * @param abcd Line (a,b)->(c,d) + * @param pqrs Line (p,q)->(r,s) + * + * @see {@link https://stackoverflow.com/a/24392281/11271734|Source} + */ +export function intersects(abcd: Line, pqrs: Line) { + const [a, b, c, d] = abcd.flat(); + const [p, q, r, s] = pqrs.flat(); + const det = (c - a) * (s - q) - (r - p) * (d - b); + if (det === 0) { + return false; + } else { + const lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; + const gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; + return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1; + } +} + +type Line = [Coordinate, Coordinate]; diff --git a/2025/09/run.ts b/2025/09/run.ts new file mode 100644 index 0000000..88783cd --- /dev/null +++ b/2025/09/run.ts @@ -0,0 +1,12 @@ +import { join } from 'path'; +import { solveFirst, solveSecond } from './index.ts'; + +const input = await Bun.file(join(__dirname, 'input.txt')).text(); + +const firstAnswer = solveFirst(input); + +console.log(firstAnswer); + +const secondAnswer = solveSecond(input); + +console.log(secondAnswer);