Skip to content

Commit

Permalink
feat: solved 2023 day 13 part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexAegis committed Dec 22, 2023
1 parent 543c57f commit 831f130
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 452 deletions.
2 changes: 1 addition & 1 deletion .github/badges/typescript/2023.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"label": "Advent of TypeScript 2023",
"message": "14/25",
"message": "15/25",
"color": "orange"
}
5 changes: 0 additions & 5 deletions solutions/typescript/2023/13/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@
"import": "./dist/p2.js",
"default": "./dist/p2.js"
},
"./parse": {
"types": "./src/parse.ts",
"import": "./dist/parse.js",
"default": "./dist/parse.js"
},
"./readme": "./readme.md"
},
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Interval } from '@alexaegis/advent-of-code-lib';
import { describe, expect, it } from 'vitest';
import { findReflectivePairings } from './matrix-reflection.js';

describe('findReflectivePairings', () => {
it('should be able to collect reflective pairs from the middle', () => {
const result = findReflectivePairings(Interval.closed(0, 8), 4);
expect(result.length).toEqual(4);
expect(result[0]).toEqual([4, 5]);
expect(result[1]).toEqual([3, 6]);
expect(result[2]).toEqual([2, 7]);
expect(result[3]).toEqual([1, 8]);
});

it('should be able to collect reflective pairs from the start', () => {
const result = findReflectivePairings(Interval.closed(0, 8), 0);
expect(result.length).toEqual(1);
expect(result[0]).toEqual([0, 1]);
});
});
61 changes: 61 additions & 0 deletions solutions/typescript/2023/13/src/internal/matrix-reflection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { GridGraph, GridGraphNode, Interval, ToString } from '@alexaegis/advent-of-code-lib';

export const matchingNodes = <
T extends ToString = string,
N extends GridGraphNode<T> = GridGraphNode<T>,
>(
a: N[],
b: N[],
): number => {
return a.zip(b).filter(([an, bn]) => an.value === bn.value).length;
};

export const findReflectivePairings = (
interval: Interval,
reflectionOrigin: number,
): [number, number][] => {
return reflectionOrigin
.interval(interval.high)
.collectValues()
.filterMap((right) => {
const left = reflectionOrigin - (right - reflectionOrigin);
return left >= interval.low ? [left, right + 1] : undefined;
});
};

export const findReflection = <
T extends ToString = string,
N extends GridGraphNode<T> = GridGraphNode<T>,
>(
gg: GridGraph<T, N>,
axis: 'row' | 'column',
smudges = 0,
skip?: number,
): number | undefined => {
const aabb = gg.boundingBox();
const axisInterval = axis === 'column' ? aabb.horizontal : aabb.vertical;
const otherAxistInterval = axis === 'column' ? aabb.vertical : aabb.horizontal;
const getNodesOfAxis = (n: number) => (axis === 'column' ? gg.getColumn(n) : gg.getRow(n));
return axisInterval.collectValues().find((index) => {
if (skip !== undefined && index === skip) {
return false;
}

const pairs = findReflectivePairings(axisInterval, index);

if (pairs.length === 0) {
return false;
}

const matching = pairs
.map(([left, right]) => {
const leftNodes = getNodesOfAxis(left)!;
const rightNodes = getNodesOfAxis(right)!;
return matchingNodes<T, N>(leftNodes, rightNodes);
})
.sum();

return matching + smudges === pairs.length * otherAxistInterval.length;
});
};
21 changes: 1 addition & 20 deletions solutions/typescript/2023/13/src/p1.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { loadTaskResources } from '@alexaegis/advent-of-code-lib';
import { describe, expect, it } from 'vitest';
import packageJson from '../package.json';
import { findReflectivePairings, p1 } from './p1.js';
import { p1 } from './p1.js';

describe('2023 13 p1', () => {
describe('the input', () => {
Expand All @@ -17,23 +17,4 @@ describe('2023 13 p1', () => {
expect(p1(resources.input)).toEqual(405);
});
});

describe('findReflectivePairings', () => {
it('should be able to collect reflective pairs from the middle', () => {
const result = findReflectivePairings(0, 8, 4);
console.log(result);
expect(result.length).toEqual(4);
expect(result[0]).toEqual([4, 5]);
expect(result[1]).toEqual([3, 6]);
expect(result[2]).toEqual([2, 7]);
expect(result[3]).toEqual([1, 8]);
});

it('should be able to collect reflective pairs from the start', () => {
const result = findReflectivePairings(0, 8, 0);
console.log(result);
expect(result.length).toEqual(1);
expect(result[0]).toEqual([0, 1]);
});
});
});
124 changes: 9 additions & 115 deletions solutions/typescript/2023/13/src/p1.ts
Original file line number Diff line number Diff line change
@@ -1,120 +1,15 @@
import {
DOUBLE_NEWLINE,
GridGraph,
GridGraphNode,
task,
type ToString,
} from '@alexaegis/advent-of-code-lib';
import { DOUBLE_NEWLINE, task } from '@alexaegis/advent-of-code-lib';
import packageJson from '../package.json';
import { findReflection } from './internal/matrix-reflection.js';

/**
* @deprecated use the one on the graph
*/
const getColumn = <T extends ToString = string, N extends GridGraphNode<T> = GridGraphNode<T>>(
gg: GridGraph<T, N>,
column: number,
): N[] | undefined => {
const aabb = gg.boundingBox();
return aabb.horizontal.contains(column)
? aabb.vertical.map((row) => {
const node = gg.getNode({ x: column, y: row });
if (!node) {
throw new Error(`problem while fetching row: ${row} column: ${column}`);
}
return node;
})
: undefined;
};

/**
* @deprecated use the one on the graph
*/
const getRow = <T extends ToString = string, N extends GridGraphNode<T> = GridGraphNode<T>>(
gg: GridGraph<T, N>,
row: number,
): N[] | undefined => {
const aabb = gg.boundingBox();
return aabb.vertical.contains(row)
? aabb.horizontal.map((column) => {
const node = gg.getNode({ x: column, y: row });
if (!node) {
throw new Error(`problem while fetching row: ${row} column: ${column}`);
}
return node;
})
: undefined;
};

const matchingNodes = <T extends ToString = string, N extends GridGraphNode<T> = GridGraphNode<T>>(
a: N[],
b: N[],
): boolean => {
return a.zip(b).every(([an, bn]) => an.value === bn.value);
};

export const findReflectivePairings = (
low: number,
high: number,
reflectionOrigin: number,
): [number, number][] => {
return reflectionOrigin
.interval(high)
.collectValues()
.filterMap((right) => {
const left = reflectionOrigin - (right - reflectionOrigin);
return left >= low ? [left, right + 1] : undefined;
});
};

const findColumnReflection = <
T extends ToString = string,
N extends GridGraphNode<T> = GridGraphNode<T>,
>(
gg: GridGraph<T, N>,
): number | undefined => {
const aabb = gg.boundingBox();
return aabb.horizontal.collectValues().find((column) => {
const pairs = findReflectivePairings(aabb.horizontal.low, aabb.horizontal.high, column);
return (
pairs.length > 0 &&
pairs.every(([left, right]) => {
const leftColumn = getColumn(gg, left);
const rightColumn = getColumn(gg, right);
return !leftColumn || !rightColumn || matchingNodes<T, N>(leftColumn, rightColumn);
})
);
});
};

const findRowReflection = <
T extends ToString = string,
N extends GridGraphNode<T> = GridGraphNode<T>,
>(
gg: GridGraph<T, N>,
): number | undefined => {
const aabb = gg.boundingBox();
return aabb.vertical.collectValues().find((row) => {
const pairs = findReflectivePairings(aabb.vertical.low, aabb.vertical.high, row);
return (
pairs.length > 0 &&
pairs.every(([top, bottom]) => {
const topRow = getRow(gg, top);
const bottomRow = getRow(gg, bottom);
return !topRow || !bottomRow || matchingNodes<T, N>(topRow, bottomRow);
})
);
});
};

export const p1 = (input: string): number => {
return input
export const p1 = (input: string): number =>
input
.split(DOUBLE_NEWLINE)
.map((m) => m.toGridGraph())
.map((gg) => {
const columnReflectionIndex = findColumnReflection(gg);
const rowReflectionIndex = findRowReflection(gg);
console.log('verticalReflectionIndex', columnReflectionIndex);
console.log('rowReflectionIndex', rowReflectionIndex);
.map((graph) => {
const columnReflectionIndex = findReflection(graph, 'column');
const rowReflectionIndex = findReflection(graph, 'row');

let value = 0;
if (columnReflectionIndex !== undefined) {
value = columnReflectionIndex + 1;
Expand All @@ -125,6 +20,5 @@ export const p1 = (input: string): number => {
return value;
})
.sum();
};

await task(p1, packageJson.aoc); // 37718 ~0ms
await task(p1, packageJson.aoc); // 37718 ~371.96ms
6 changes: 3 additions & 3 deletions solutions/typescript/2023/13/src/p2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import { describe, expect, it } from 'vitest';
import packageJson from '../package.json';
import { p2 } from './p2.js';

describe.skip('2023 13 p2', () => {
describe('2023 13 p2', () => {
describe('the input', () => {
it('should solve the input', async () => {
const { input } = await loadTaskResources(packageJson.aoc);
expect(p2(input)).toEqual(0);
expect(p2(input)).toEqual(40_995);
});
});

describe('example 1', () => {
it('should be solved', async () => {
const { input } = await loadTaskResources(packageJson.aoc, 'example.1.txt');
expect(p2(input)).toEqual(0);
expect(p2(input)).toEqual(400);
});
});
});
Loading

0 comments on commit 831f130

Please sign in to comment.