advent of code 2025 in ts and nix
at main 2.9 kB view raw
1const file = await Bun.file("../../shared/08/input.txt").text(); 2 3// Parse junction coordinates 4const junctions = file 5 .trim() 6 .split("\n") 7 .map((line) => { 8 const [x, y, z] = line.split(",").map(Number); 9 return { x, y, z }; 10 }); 11 12// Calculate distance between two junctions 13function distance( 14 a: { x: number; y: number; z: number }, 15 b: { x: number; y: number; z: number } 16): number { 17 return Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2 + (a.z - b.z) ** 2); 18} 19 20// Generate all pairs with distances 21const pairs = []; 22for (let i = 0; i < junctions.length; i++) { 23 for (let j = i + 1; j < junctions.length; j++) { 24 pairs.push({ 25 i, 26 j, 27 distance: distance(junctions[i], junctions[j]), 28 }); 29 } 30} 31 32// Sort by distance 33pairs.sort((a, b) => a.distance - b.distance); 34 35// Union-Find data structure 36class UnionFind { 37 parent: number[]; 38 size: number[]; 39 40 constructor(n: number) { 41 this.parent = Array.from({ length: n }, (_, i) => i); 42 this.size = Array(n).fill(1); 43 } 44 45 find(x: number): number { 46 if (this.parent[x] !== x) { 47 this.parent[x] = this.find(this.parent[x]); 48 } 49 return this.parent[x]; 50 } 51 52 union(x: number, y: number): boolean { 53 const rootX = this.find(x); 54 const rootY = this.find(y); 55 56 if (rootX === rootY) return false; 57 58 if (this.size[rootX] < this.size[rootY]) { 59 this.parent[rootX] = rootY; 60 this.size[rootY] += this.size[rootX]; 61 } else { 62 this.parent[rootY] = rootX; 63 this.size[rootX] += this.size[rootY]; 64 } 65 66 return true; 67 } 68 69 getCircuitSizes(): number[] { 70 const circuits = new Map<number, number>(); 71 for (let i = 0; i < this.parent.length; i++) { 72 const root = this.find(i); 73 circuits.set(root, this.size[root]); 74 } 75 return Array.from(circuits.values()).sort((a, b) => b - a); 76 } 77 78 getCircuitCount(): number { 79 const roots = new Set<number>(); 80 for (let i = 0; i < this.parent.length; i++) { 81 roots.add(this.find(i)); 82 } 83 return roots.size; 84 } 85} 86 87(() => { 88 // Part 1: After 1000 connections, product of top 3 circuit sizes 89 const uf = new UnionFind(junctions.length); 90 91 for (let i = 0; i < 1000; i++) { 92 uf.union(pairs[i].i, pairs[i].j); 93 } 94 95 const circuitSizes = uf.getCircuitSizes(); 96 const top3 = circuitSizes.slice(0, 3); 97 const product = top3[0] * top3[1] * top3[2]; 98 99 console.log("part 1:", product); 100})(); 101 102(() => { 103 // Part 2: Find when all junctions form a single circuit 104 const uf = new UnionFind(junctions.length); 105 106 for (let i = 0; i < pairs.length; i++) { 107 uf.union(pairs[i].i, pairs[i].j); 108 109 if (uf.getCircuitCount() === 1) { 110 // Found the connection that unified everything 111 const pair = pairs[i]; 112 const product = junctions[pair.i].x * junctions[pair.j].x; 113 console.log("part 2:", product); 114 break; 115 } 116 } 117})();