From 7a58627132f6a1c8b283f9cd0c7f80e14215dc5d Mon Sep 17 00:00:00 2001 From: chrisly42 Date: Mon, 8 Dec 2025 06:58:11 +0100 Subject: [PATCH] Day 8. --- src/aoc2025/Day08.kt | 123 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/aoc2025/Day08.kt diff --git a/src/aoc2025/Day08.kt b/src/aoc2025/Day08.kt new file mode 100644 index 0000000..736c671 --- /dev/null +++ b/src/aoc2025/Day08.kt @@ -0,0 +1,123 @@ +package aoc2025 + +import println +import readInput +import splitInts +import kotlin.math.sqrt + +/* +--- Day 8: Playground --- +https://adventofcode.com/2025/day/8 +*/ +fun main() { + + val inlineTestInput = """ +162,817,812 +57,618,57 +906,360,560 +592,479,940 +352,342,300 +466,668,158 +542,29,236 +431,825,988 +739,650,466 +52,470,668 +216,146,977 +819,987,18 +117,168,530 +805,96,715 +346,949,466 +970,615,88 +941,993,340 +862,61,35 +984,92,344 +425,690,689 +""" + + fun dist(n1: IntArray, n2: IntArray) = + sqrt(((n1[0] - n2[0]).toFloat() * (n1[0] - n2[0]) + (n1[1] - n2[1]).toFloat() * (n1[1] - n2[1]) + (n1[2] - n2[2]).toFloat() * (n1[2] - n2[2]))) + + fun find(parent: IntArray, n: Int): Int { + if (parent[n] != n) { + parent[n] = find(parent, parent[n]) + } + return parent[n] + } + + fun union(parent: IntArray, n1: Int, n2: Int): Boolean { + val r1 = find(parent, n1) + val r2 = find(parent, n2) + if (r1 != r2) { + parent[r1] = r2 + return true + } + return false + } + + // priority queue would have been more efficient... who cares + fun createDistances(nodes: Array): Iterable, Float>> { + val distances = ArrayList, Float>>() + for (i1 in 0 until nodes.size) { + for (i2 in i1 + 1 until nodes.size) { + val d = dist(nodes[i1], nodes[i2]) + distances.add((i1 to i2) to d) + } + } + distances.sortBy { it.second } + return distances + } + + fun part1(input: List, numConnections: Int): Long { + val nodes = input.map { it.splitInts(",").toIntArray() }.toTypedArray() + val distances = createDistances(nodes) + + val n = nodes.size + var numCircuits = 0 + val unionFindParentArray = IntArray(n) { it } + for (d in distances) { + val (n1, n2) = d.first + union(unionFindParentArray, n1, n2) + numCircuits++ + if (numCircuits == numConnections) break + } + + val circuitSizes = LongArray(n) + for (i in 0 until n) { + circuitSizes[find(unionFindParentArray, i)]++ + } + return circuitSizes.sortedDescending().take(3).fold(1L) { acc, l -> acc * l } + } + + fun part2(input: List): Int { + val nodes = input.map { it.splitInts(",").toIntArray() }.toTypedArray() + val distances = createDistances(nodes) + + val n = nodes.size + var numCircuits = 1 + val unionFindParentArray = IntArray(n) { it } + for (d in distances) { + val (n1, n2) = d.first + if (union(unionFindParentArray, n1, n2)) { + numCircuits++ + if (numCircuits == n) { + return nodes[n1][0] * nodes[n2][0] + } + } + } + return -1 + } + + // test if implementation meets criteria from the description, like: + val testInput = inlineTestInput.trim().reader().readLines() + //val testInput = readInput("aoc2025/Day08_test") + val testInputPart1Result = part1(testInput, 10) + println("Part 1 Test: $testInputPart1Result") + val testInputPart2Result = part2(testInput) + println("Part 2 Test: $testInputPart2Result") + check(testInputPart1Result == 40L) + check(testInputPart2Result == 25272) + + val input = readInput("aoc2025/Day08") + part1(input, 1000).println() + part2(input).println() +}