Day 8.
This commit is contained in:
parent
5fc0e8756a
commit
7a58627132
123
src/aoc2025/Day08.kt
Normal file
123
src/aoc2025/Day08.kt
Normal file
@ -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<IntArray>): Iterable<Pair<Pair<Int, Int>, Float>> {
|
||||
val distances = ArrayList<Pair<Pair<Int, Int>, 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<String>, 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<String>): 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()
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user