Skip to content

Commit 0f3914d

Browse files
committed
2024D23: part 2
1 parent d232933 commit 0f3914d

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

2024/src/2024/day23/day23.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('2024 Day 23', () => {
77
});
88

99
test('Part 2', async () => {
10-
expect(await part2('testInput1')).toEqual(31);
11-
expect(await part2('input')).toEqual(29379307);
10+
expect(await part2('testInput1')).toEqual("co,de,ka,ta");
11+
expect(await part2('input')).toEqual("bg,bl,ch,fn,fv,gd,jn,kk,lk,pv,rr,tb,vw");
1212
});
1313
});

2024/src/2024/day23/day23.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,71 @@ export async function part1(inputFile: string) {
66
}
77

88
export async function part2(inputFile: string) {
9-
return await day23(inputFile);
9+
return await day23(inputFile, findLargestParty);
1010
}
1111

12-
async function day23(inputFile: string, calcFn?: (lines: string[]) => number) {
12+
async function day23(inputFile: string, calcFn?: (lines: string[]) => number | string) {
1313
const inputPath = path.join(__dirname, inputFile);
1414
const lines = await readInputLineByLine(inputPath);
1515

1616
return calcFn?.(lines);
1717
}
1818

1919
function findComputerTriplets(lines: string[]) {
20-
const adjacencyList: { [key: string]: Set<string>} = {};
20+
const adjacencyList = getAdjacencyList(lines);
21+
22+
return getTrianglesStartingWithT(adjacencyList);
23+
}
24+
25+
// Bron–Kerbosch Algorithm:
26+
// It operates on three sets:
27+
// - R (Current Clique): Nodes included in the current clique.
28+
// - P (Candidates): Nodes that can be added to the current clique.
29+
// - X (Excluded): Nodes already considered and excluded from the current clique.
30+
// At each step:
31+
// - If P and X are empty, R is a maximal clique.
32+
// - A pivot is selected to reduce the search space and optimize performance.
33+
// Recursive calls refine these sets to explore possible cliques.
34+
35+
function findLargestParty(lines: string[]) {
36+
const adjacencyList = getAdjacencyList(lines);
37+
38+
const findLargestParties = (adjacencyList: { [key: string]: Set<string> }) => {
39+
const parties: string[][] = [];
40+
41+
const bronKerbosch = (r: Set<string>, p: Set<string>, x: Set<string>) => {
42+
if (p.size === 0 && x.size === 0) {
43+
parties.push([...r]);
44+
return;
45+
}
46+
47+
const pivot = p.size > 0 ? [...p][0] : null;
48+
const pivotNeighbors = pivot ? adjacencyList[pivot] : new Set();
49+
50+
for (const node of [...p].filter((n) => !pivotNeighbors.has(n))) {
51+
bronKerbosch(
52+
new Set([...r, node]),
53+
new Set([...p].filter((n) => adjacencyList[node].has(n))),
54+
new Set([...x].filter((n) => adjacencyList[node].has(n))),
55+
);
56+
p.delete(node);
57+
x.add(node);
58+
}
59+
}
60+
61+
bronKerbosch(new Set(), new Set(Object.keys(adjacencyList)), new Set());
62+
return parties;
63+
}
64+
65+
const findLargestParty = (parties: string[][]) => {
66+
return parties.reduce((max, party) => (party.length > max.length ? party : max), []);
67+
}
68+
69+
return findLargestParty(findLargestParties(adjacencyList)).sort().join(",");
70+
}
71+
72+
function getAdjacencyList(lines: string[]) {
73+
const adjacencyList: { [key: string]: Set<string> } = {};
2174
for (const connection of lines) {
2275
const [a, b] = connection.split("-");
2376
if (!adjacencyList[a])
@@ -28,7 +81,10 @@ function findComputerTriplets(lines: string[]) {
2881
adjacencyList[a].add(b);
2982
adjacencyList[b].add(a);
3083
}
84+
return adjacencyList;
85+
}
3186

87+
function getTrianglesStartingWithT(adjacencyList: { [p: string]: Set<string> }) {
3288
const triangles: Set<string> = new Set();
3389
let trianglesStartingWithT = 0;
3490
for (const [node, neighbors] of Object.entries(adjacencyList)) {
@@ -46,7 +102,6 @@ function findComputerTriplets(lines: string[]) {
46102
}
47103
}
48104
}
49-
50105
[...triangles].forEach((triangle: string) => {
51106
const split = triangle.split(",")
52107
if (split.some(s => s.startsWith("t"))) {

0 commit comments

Comments
 (0)