generated from eric/adventofcode2023
120 lines
3.1 KiB
JavaScript
120 lines
3.1 KiB
JavaScript
import { readFileSync } from 'node:fs';
|
|
|
|
let sampleMode = false;
|
|
let usedArray = [];
|
|
|
|
const sampleArray = readFileSync('sample.txt').toString().split("\n");
|
|
const inputArray = readFileSync('input.txt').toString().split("\n");
|
|
|
|
if (sampleMode) {
|
|
usedArray = sampleArray;
|
|
} else {
|
|
usedArray = inputArray;
|
|
}
|
|
|
|
// Part One
|
|
|
|
console.time("part1");
|
|
|
|
let coordinatesArray = [];
|
|
|
|
for (const element of usedArray) {
|
|
const coordinates = element.split(",");
|
|
coordinatesArray.push({ x: Number.parseInt(coordinates[0]), y: Number.parseInt(coordinates[1]), z: Number.parseInt(coordinates[2]) });
|
|
}
|
|
|
|
let segments = [];
|
|
let parent = {};
|
|
|
|
for (let i = 0; i < coordinatesArray.length; i++) {
|
|
for (let j = i + 1; j < coordinatesArray.length; j++) {
|
|
const x2 = Math.pow(coordinatesArray[i].x - coordinatesArray[j].x, 2);
|
|
const y2 = Math.pow(coordinatesArray[i].y - coordinatesArray[j].y, 2);
|
|
const z2 = Math.pow(coordinatesArray[i].z - coordinatesArray[j].z, 2);
|
|
const distance = Math.sqrt(x2 + y2 + z2);
|
|
segments.push({ from: i, to: j, distance });
|
|
}
|
|
}
|
|
|
|
segments.sort((a, b) => a.distance - b.distance);
|
|
const shortest = segments.slice(0, sampleMode ? 10 : 1000);
|
|
|
|
for (const seg of shortest) {
|
|
union(seg.from, seg.to);
|
|
}
|
|
|
|
const circuits = {};
|
|
for (const seg of shortest) {
|
|
const root = find(seg.from);
|
|
circuits[root] = circuits[root] || new Set();
|
|
circuits[root].add(seg.from);
|
|
circuits[root].add(seg.to);
|
|
}
|
|
|
|
const circuitList = Object.values(circuits);
|
|
const sizes = circuitList.map(nodes => nodes.size).sort((a, b) => b - a);
|
|
const result = sizes[0] * sizes[1] * sizes[2];
|
|
|
|
console.timeEnd("part1");
|
|
console.log(result);
|
|
|
|
// Part Two
|
|
|
|
console.time("part2");
|
|
|
|
coordinatesArray = [];
|
|
|
|
for (const element of usedArray) {
|
|
const coordinates = element.split(",");
|
|
coordinatesArray.push({ x: Number.parseInt(coordinates[0]), y: Number.parseInt(coordinates[1]), z: Number.parseInt(coordinates[2]) });
|
|
}
|
|
|
|
segments = [];
|
|
parent = {};
|
|
|
|
for (let i = 0; i < coordinatesArray.length; i++) {
|
|
for (let j = i + 1; j < coordinatesArray.length; j++) {
|
|
const x2 = Math.pow(coordinatesArray[i].x - coordinatesArray[j].x, 2);
|
|
const y2 = Math.pow(coordinatesArray[i].y - coordinatesArray[j].y, 2);
|
|
const z2 = Math.pow(coordinatesArray[i].z - coordinatesArray[j].z, 2);
|
|
const distance = Math.sqrt(x2 + y2 + z2);
|
|
segments.push({ from: i, to: j, distance });
|
|
}
|
|
}
|
|
|
|
segments.sort((a, b) => a.distance - b.distance);
|
|
let circuitCount = coordinatesArray.length;
|
|
let lastSegment;
|
|
for (const seg of segments) {
|
|
const rootFrom = find(seg.from);
|
|
const rootTo = find(seg.to);
|
|
|
|
if (rootFrom !== rootTo) {
|
|
union(seg.from, seg.to);
|
|
circuitCount--;
|
|
lastSegment = seg;
|
|
|
|
if (circuitCount === 1) break;
|
|
}
|
|
}
|
|
|
|
const result2 = coordinatesArray[lastSegment.from].x * coordinatesArray[lastSegment.to].x;
|
|
|
|
console.timeEnd("part2");
|
|
console.log(result2);
|
|
|
|
// functions
|
|
|
|
function find(x) {
|
|
if (parent[x] === undefined) parent[x] = x;
|
|
if (parent[x] !== x) parent[x] = find(parent[x]);
|
|
return parent[x];
|
|
}
|
|
|
|
function union(a, b) {
|
|
const rootA = find(a);
|
|
const rootB = find(b);
|
|
if (rootA !== rootB) {
|
|
parent[rootA] = rootB;
|
|
}
|
|
} |