diff --git a/2024/23/2024-23.run.xml b/2024/23/2024-23.run.xml new file mode 100644 index 0000000..d99eb4d --- /dev/null +++ b/2024/23/2024-23.run.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/2024/23/index.test.ts b/2024/23/index.test.ts new file mode 100644 index 0000000..a1d83f5 --- /dev/null +++ b/2024/23/index.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from 'bun:test'; +import { solveFirst, solveSecond } from './index.ts'; + +describe('2024-23', () => { + const testInput = `kh-tc +qp-kh +de-cg +ka-co +yn-aq +qp-ub +cg-tb +vc-aq +tb-ka +wh-tc +yn-cg +kh-ub +ta-co +de-co +tc-td +tb-wq +wh-td +ta-ka +td-qp +aq-cg +wq-ub +ub-vc +de-ta +wq-aq +wq-vc +wh-yn +ka-de +kh-ta +co-tc +wh-qp +tb-vc +td-yn`; + it('first', () => { + expect(solveFirst(testInput)).toBe(7); + }); + it('second', () => { + expect(solveSecond(testInput)).toBe('co,de,ka,ta'); + }); +}); diff --git a/2024/23/index.ts b/2024/23/index.ts new file mode 100644 index 0000000..6041d32 --- /dev/null +++ b/2024/23/index.ts @@ -0,0 +1,63 @@ +import { uniqueCombinations } from '../../utils/array.ts'; + +export function solveFirst(input: string): number { + const connections = extractConnections(input); + + const found = new Set(); + for (let key in connections) { + if (!key.startsWith('t')) { + continue; + } + getTriangles(connections, key).forEach((t) => found.add(t)); + } + + return found.size; +} + +function getTriangles(connections: Record, key: string) { + const tripplePairs = uniqueCombinations(connections[key]).filter(({ a, b }) => + connections[a].includes(b) + ); + return tripplePairs.map(({ a, b }) => [key, a, b].toSorted().join(',')); +} + +function extractConnections(input: string) { + const connections: Record = {}; + const pairs = input.split('\n').map((r) => r.split('-') as [string, string]); + + pairs.forEach(([a, b]) => { + connections[a] = [...(connections[a] || []), b]; + connections[b] = [...(connections[b] || []), a]; + }); + return connections; +} + +export function solveSecond(input: string): string { + const connections = extractConnections(input); + + const triples = new Set(); + for (let key in connections) { + getTriangles(connections, key).forEach((t) => triples.add(t)); + } + const triangles = [...triples]; + + let maxSize = 0; + const triaggs: string[][] = []; + for (let key in connections) { + const triags = triangles.filter((t) => t.includes(key)); + + if (triags.length > maxSize) { + maxSize = triags.length; + } + triaggs.push(triags); + } + const notInMax = new Set( + triaggs + .filter((ts) => ts.length < maxSize) + .map((ts) => ts.map((t) => t.split(','))) + .flat(2) + ); + const allNodes = new Set(Object.keys(connections)); + + return [...allNodes.difference(notInMax)].toSorted().join(','); +} diff --git a/2024/23/run.ts b/2024/23/run.ts new file mode 100644 index 0000000..88783cd --- /dev/null +++ b/2024/23/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); diff --git a/utils/array.ts b/utils/array.ts index 93f0fd5..d587332 100644 --- a/utils/array.ts +++ b/utils/array.ts @@ -115,6 +115,27 @@ export function combinations(arr: ReadonlyArray): { a: E; b: E }[] { .filter((c) => !!c); } +/** + * Returns an array with every unique combination of every element in an array. + * The combination array will have a length of `n! / ((n-2)! * 2)` for an array of length `n`. + * @example + * ```typescript + * const arr = [0, 1, 2] + * + * combinations(arr) === [ + * {a: 0, b: 1}, + * {a: 0, b: 2}, + * {a: 1, b: 2} + * ] + * ``` + * @param arr + */ +export function uniqueCombinations(arr: ReadonlyArray): { a: E; b: E }[] { + return arr.flatMap((a, aI) => + arr.flatMap((b, bI) => (a !== b && aI > bI ? [{ a, b }] : [])) + ); +} + /** * Returns a filter lambda to be used in array.filter() to only allow the * first occurrence of duplicate values.