diff --git a/solutions/typescript/2018/06/src/interpret.function.ts b/solutions/typescript/2018/06/src/interpret.function.ts index 80131a013..ad12224f1 100644 --- a/solutions/typescript/2018/06/src/interpret.function.ts +++ b/solutions/typescript/2018/06/src/interpret.function.ts @@ -1,12 +1,11 @@ -import { split } from '@alexaegis/advent-of-code-lib'; -import { Coord } from './model/coord.class.js'; +import { Vec2, split } from '@alexaegis/advent-of-code-lib'; -export const interpret = (input: string): Coord[] => { - const points: Coord[] = []; +export const interpret = (input: string): Vec2[] => { + const points: Vec2[] = []; for (const line of split(input)) { if (line) { - const lineSplit = line.split(', '); - points.push(new Coord(Number(lineSplit[1]), Number(lineSplit[0]))); + const [y, x] = line.splitIntoStringPair(', '); + points.push(new Vec2(Number.parseInt(x, 10), Number.parseInt(y, 10))); } } return points; diff --git a/solutions/typescript/2018/06/src/model/args.interface.ts b/solutions/typescript/2018/06/src/model/args.interface.ts deleted file mode 100644 index 4ac4edfef..000000000 --- a/solutions/typescript/2018/06/src/model/args.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface Args { - limit: number; -} diff --git a/solutions/typescript/2018/06/src/model/coord.class.spec.ts b/solutions/typescript/2018/06/src/model/coord.class.spec.ts deleted file mode 100644 index d3b69a906..000000000 --- a/solutions/typescript/2018/06/src/model/coord.class.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { Coord } from './coord.class.js'; - -describe('2018 - Day 6 - Coord', () => { - const a: Coord = new Coord(1, 1); - const b: Coord = new Coord(3, 3); - const c: Coord = new Coord(7, 2); - - it('should the manhattan distance between (1, 1) and (3, 3) be 4', () => { - expect(a.manhattanCoord(b)).toEqual(4); - }); - - it('should the manhattan distance between (3, 3) and (7, 2) be 4', () => { - expect(b.manhattanCoord(c)).toEqual(5); - }); - - it('should the that the manhattan distance is commutative', () => { - expect(a.manhattanCoord(b)).toEqual(b.manhattanCoord(a)); - expect(a.manhattanCoord(c)).toEqual(c.manhattanCoord(a)); - }); -}); diff --git a/solutions/typescript/2018/06/src/model/coord.class.ts b/solutions/typescript/2018/06/src/model/coord.class.ts deleted file mode 100644 index 6dd6e672e..000000000 --- a/solutions/typescript/2018/06/src/model/coord.class.ts +++ /dev/null @@ -1,24 +0,0 @@ -export class Coord { - public constructor( - public x: number, - public y: number, - ) {} - - public add(coord: Coord): this { - this.x += coord.x; - this.y -= coord.y; // TODO: Psst, you didn't see me. - return this; - } - - public manhattanCoord(coord: Coord): number { - return this.manhattan(coord.x, coord.y); - } - - public manhattan(x: number, y: number): number { - return Math.abs(x - this.x) + Math.abs(y - this.y); - } - - public toString(): string { - return `${this.x},${this.y}`; - } -} diff --git a/solutions/typescript/2018/06/src/p1.ts b/solutions/typescript/2018/06/src/p1.ts index c34172d78..8eee19ed9 100644 --- a/solutions/typescript/2018/06/src/p1.ts +++ b/solutions/typescript/2018/06/src/p1.ts @@ -1,69 +1,38 @@ -import { task } from '@alexaegis/advent-of-code-lib'; +import { BoundingBox, Vec2, task } from '@alexaegis/advent-of-code-lib'; import packageJson from '../package.json'; import { interpret } from './interpret.function.js'; -import { Coord } from './model/coord.class.js'; export const p1 = (input: string): number | undefined => { const points = interpret(input); - let boundaryTop: Coord | undefined; - let boundaryRight: Coord | undefined; - let boundaryBottom: Coord | undefined; - let boundaryLeft: Coord | undefined; + const aabb = BoundingBox.fromVectors(points); + aabb.pad(0, 1); + const bucket = new Map(); - for (const point of points) { - if (boundaryTop === undefined || boundaryTop.y >= point.y) { - boundaryTop = point; - } - if (boundaryRight === undefined || boundaryRight.x <= point.x) { - boundaryRight = point; - } - if (boundaryBottom === undefined || boundaryBottom.y <= point.y) { - boundaryBottom = point; - } - if (boundaryLeft === undefined || boundaryLeft.x >= point.x) { - boundaryLeft = point; - } - } - - if (boundaryTop && boundaryRight && boundaryBottom && boundaryLeft) { - const boundaryStart: Coord = new Coord(boundaryLeft.x, boundaryTop.y); - const boundaryEnd: Coord = new Coord(boundaryRight.x, boundaryBottom.y + 1); - const bucket = new Map(); - for (const point of points) { - bucket.set(point.toString(), []); - } - for (let x = boundaryStart.x; x < boundaryEnd.x; x++) { - for (let y = boundaryStart.y; y < boundaryEnd.y; y++) { - const ordered: Coord[] = points.sort( - (a, b) => a.manhattan(x, y) - b.manhattan(x, y), - ); - if (ordered[0]?.manhattan(x, y) !== ordered[1]?.manhattan(x, y)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const b = bucket.get(ordered[0]!.toString()); - if (b) { - b.push(new Coord(x, y)); - } - } + for (const x of aabb.horizontal.iter()) { + for (const y of aabb.vertical.iter()) { + const ordered: Vec2[] = points.sort((a, b) => a.manhattan(x, y) - b.manhattan(x, y)); + if (ordered[0]?.manhattan(x, y) !== ordered[1]?.manhattan(x, y)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const b = bucket.getOrAdd(ordered[0]!.toString(), () => []); + b.push(new Vec2(x, y)); } } - const bound: number[] = []; - for (const territory of bucket.values()) { - if ( - !territory.some( - (point) => - point.x <= boundaryStart.x || - point.y <= boundaryStart.y || - point.x >= boundaryEnd.x || - point.y >= boundaryEnd.y - 1, // magic boundary bandaid - ) - ) { - bound.push(territory.length); - } + } + const bound: number[] = []; + for (const territory of bucket.values()) { + if ( + !territory.some( + (point) => + point.x <= aabb.left || + point.y <= aabb.top || + point.x >= aabb.right || + point.y >= aabb.bottom - 1, // magic boundary bandaid + ) + ) { + bound.push(territory.length); } - return bound.reduce((acc, next) => (next > acc ? next : acc), 0); - } else { - return undefined; } + return bound.reduce((acc, next) => (next > acc ? next : acc), 0); }; await task(p1, packageJson.aoc); // 3006 ~230ms diff --git a/solutions/typescript/2018/06/src/p2.spec.ts b/solutions/typescript/2018/06/src/p2.spec.ts index a4ddae2ec..1ae7c87f6 100644 --- a/solutions/typescript/2018/06/src/p2.spec.ts +++ b/solutions/typescript/2018/06/src/p2.spec.ts @@ -1,8 +1,7 @@ import { loadTaskResources } from '@alexaegis/advent-of-code-lib'; import { describe, expect, it } from 'vitest'; import packageJson from '../package.json'; -import type { Args } from './model/args.interface.js'; -import { p2 } from './p2.js'; +import { p2, type Args } from './p2.js'; describe('2018 - Day 6 - Part Two', () => { it('should solve the input', async () => { diff --git a/solutions/typescript/2018/06/src/p2.ts b/solutions/typescript/2018/06/src/p2.ts index 7a6b5764e..fc4849ca7 100644 --- a/solutions/typescript/2018/06/src/p2.ts +++ b/solutions/typescript/2018/06/src/p2.ts @@ -1,8 +1,10 @@ -import { task } from '@alexaegis/advent-of-code-lib'; +import { BoundingBox, task } from '@alexaegis/advent-of-code-lib'; import packageJson from '../package.json'; import { interpret } from './interpret.function.js'; -import type { Args } from './model/args.interface.js'; -import { Coord } from './model/coord.class.js'; + +export interface Args { + limit: number; +} /** * @@ -11,44 +13,21 @@ import { Coord } from './model/coord.class.js'; */ export const p2 = (input: string, args: Args | undefined): number | undefined => { const points = interpret(input); - let boundaryTop: Coord | undefined; - let boundaryRight: Coord | undefined; - let boundaryBottom: Coord | undefined; - let boundaryLeft: Coord | undefined; + const aabb = BoundingBox.fromVectors(points); - for (const point of points) { - if (boundaryTop === undefined || boundaryTop.y >= point.y) { - boundaryTop = point; - } - if (boundaryRight === undefined || boundaryRight.x <= point.x) { - boundaryRight = point; - } - if (boundaryBottom === undefined || boundaryBottom.y <= point.y) { - boundaryBottom = point; - } - if (boundaryLeft === undefined || boundaryLeft.x >= point.x) { - boundaryLeft = point; - } - } + let area = 0; - if (boundaryTop && boundaryRight && boundaryBottom && boundaryLeft) { - const boundaryStart: Coord = new Coord(boundaryLeft.x, boundaryTop.y); - const boundaryEnd: Coord = new Coord(boundaryRight.x, boundaryBottom.y + 1); - let area = 0; - for (let x = boundaryStart.x; x < boundaryEnd.x; x++) { - for (let y = boundaryStart.y; y < boundaryEnd.y; y++) { - if ( - points.map((a) => a.manhattan(x, y)).reduce((acc, next) => (acc += next)) < - (args ? args.limit : 0) - ) { - area++; - } + for (const x of aabb.horizontal.iter()) { + for (const y of aabb.vertical.iter()) { + if ( + points.map((a) => a.manhattan(x, y)).reduce((acc, next) => (acc += next)) < + (args ? args.limit : 0) + ) { + area++; } } - return area; - } else { - return undefined; } + return area; }; await task(p2, packageJson.aoc); // 42998 ~46ms diff --git a/solutions/typescript/libs/lib/src/math/common/interval.class.ts b/solutions/typescript/libs/lib/src/math/common/interval.class.ts index e65665e31..c1e927d2c 100644 --- a/solutions/typescript/libs/lib/src/math/common/interval.class.ts +++ b/solutions/typescript/libs/lib/src/math/common/interval.class.ts @@ -229,7 +229,7 @@ export class Interval implements IntervalLike, IntervalQualifier { reduce(reducer: (accumulator: A, next: number) => A, initialValue: A): A { let accumulator = initialValue; - for (const item of this.walk()) { + for (const item of this.iter()) { accumulator = reducer(accumulator, item); } return accumulator; @@ -506,14 +506,14 @@ export class Interval implements IntervalLike, IntervalQualifier { return Interval.isAboveLow(this, n); } - *walk(): Generator { + *iter(): Generator { for (let i = this.lowest(); this.contains(i); i++) { yield i; } } collectValues(): number[] { - return [...this.walk()]; + return [...this.iter()]; } /**