Skip to content

Commit a479542

Browse files
committed
feat: 2024 Day 23
1 parent 5dea1fe commit a479542

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

2024/day/23/part/1/solve.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("example", () => {
6+
const input = `\
7+
kh-tc
8+
qp-kh
9+
de-cg
10+
ka-co
11+
yn-aq
12+
qp-ub
13+
cg-tb
14+
vc-aq
15+
tb-ka
16+
wh-tc
17+
yn-cg
18+
kh-ub
19+
ta-co
20+
de-co
21+
tc-td
22+
tb-wq
23+
wh-td
24+
ta-ka
25+
td-qp
26+
aq-cg
27+
wq-ub
28+
ub-vc
29+
de-ta
30+
wq-aq
31+
wq-vc
32+
wh-yn
33+
ka-de
34+
kh-ta
35+
co-tc
36+
wh-qp
37+
tb-vc
38+
td-yn`;
39+
40+
assertEquals(solve(input), 7);
41+
});

2024/day/23/part/1/solve.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export default function solve(input: string) {
2+
const connections = input.split("\n").map((line) => line.split("-"));
3+
const edges = new Map<string, Set<string>>();
4+
for (const [u, v] of connections) {
5+
edges.get(u)?.add(v) ?? edges.set(u, new Set([v]));
6+
edges.get(v)?.add(u) ?? edges.set(v, new Set([u]));
7+
}
8+
const interconnections = new Set<string>();
9+
for (const [u, uNeighbors] of edges) {
10+
for (const v of uNeighbors) {
11+
const vNeighbors = edges.get(v);
12+
if (!vNeighbors?.has(u)) continue;
13+
for (const w of vNeighbors) {
14+
const wNeighbors = edges.get(w);
15+
if (!wNeighbors?.has(u)) continue;
16+
interconnections.add([u, v, w].sort().join(","));
17+
}
18+
}
19+
}
20+
let count = 0;
21+
for (const interconnection of interconnections) {
22+
if (interconnection.split(",").some((n) => n.startsWith("t"))) count++;
23+
}
24+
return count;
25+
}

2024/day/23/part/2/solve.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import solve from "./solve.ts";
2+
3+
import { assertEquals } from "@std/assert";
4+
5+
Deno.test("example", () => {
6+
const input = `\
7+
kh-tc
8+
qp-kh
9+
de-cg
10+
ka-co
11+
yn-aq
12+
qp-ub
13+
cg-tb
14+
vc-aq
15+
tb-ka
16+
wh-tc
17+
yn-cg
18+
kh-ub
19+
ta-co
20+
de-co
21+
tc-td
22+
tb-wq
23+
wh-td
24+
ta-ka
25+
td-qp
26+
aq-cg
27+
wq-ub
28+
ub-vc
29+
de-ta
30+
wq-aq
31+
wq-vc
32+
wh-yn
33+
ka-de
34+
kh-ta
35+
co-tc
36+
wh-qp
37+
tb-vc
38+
td-yn`;
39+
40+
assertEquals(solve(input), "co,de,ka,ta");
41+
});

2024/day/23/part/2/solve.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
type Graph<N> = { nodes: ReadonlySet<N>; neighbors(n: N): ReadonlySet<N> };
2+
3+
function findLargestClique<N>(graph: Graph<N>) {
4+
let maxClique = new Set<N>();
5+
function bronKerbosch(R: ReadonlySet<N>, P: Set<N>, X: Set<N>) {
6+
if (P.size === 0 && X.size === 0) {
7+
if (R.size > maxClique.size) maxClique = new Set(R);
8+
return;
9+
}
10+
for (const v of P) {
11+
const vNeighbors = graph.neighbors(v);
12+
bronKerbosch(
13+
new Set(R).add(v),
14+
P.intersection(vNeighbors),
15+
X.intersection(vNeighbors),
16+
);
17+
P.delete(v);
18+
X.add(v);
19+
}
20+
}
21+
bronKerbosch(new Set<N>(), new Set(graph.nodes), new Set<N>());
22+
return maxClique;
23+
}
24+
25+
export default function solve(input: string) {
26+
const connections = input.split("\n").map((line) => line.split("-"));
27+
const edges = new Map<string, Set<string>>();
28+
for (const [u, v] of connections) {
29+
edges.get(u)?.add(v) ?? edges.set(u, new Set([v]));
30+
edges.get(v)?.add(u) ?? edges.set(v, new Set([u]));
31+
}
32+
const graph: Graph<string> = {
33+
nodes: new Set(edges.keys()),
34+
neighbors: (n: string) => edges.get(n) ?? new Set(),
35+
};
36+
return findLargestClique(graph).values().toArray().sort().join(",");
37+
}

0 commit comments

Comments
 (0)