Solve 2024-23
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="2024-23" type="BunRunConfiguration">
|
||||||
|
<option name="program" value="2024/23/run.ts" />
|
||||||
|
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { uniqueCombinations } from '../../utils/array.ts';
|
||||||
|
|
||||||
|
export function solveFirst(input: string): number {
|
||||||
|
const connections = extractConnections(input);
|
||||||
|
|
||||||
|
const found = new Set<string>();
|
||||||
|
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<string, string[]>, 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<string, string[]> = {};
|
||||||
|
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<string>();
|
||||||
|
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(',');
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
@@ -115,6 +115,27 @@ export function combinations<E>(arr: ReadonlyArray<E>): { a: E; b: E }[] {
|
|||||||
.filter((c) => !!c);
|
.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<E>(arr: ReadonlyArray<E>): { 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
|
* Returns a filter lambda to be used in array.filter() to only allow the
|
||||||
* first occurrence of duplicate values.
|
* first occurrence of duplicate values.
|
||||||
|
|||||||
Reference in New Issue
Block a user