Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/kotlin/cz/glubo/adventofcode/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,8 @@ fun main(args: Array<String>) {
"2025day8p2" to InputToLongCommand { y2025day8part2(it) },
"2025day10p1" to InputToLongCommand { y2025day10part1(it) },
"2025day10p2" to InputToLongCommand { y2025day10part2(it) },
"2024day25p1" to InputToLongCommand { y2024day25part1(it) },
"2024day25p2" to InputToLongCommand { y2024day25part2(it) },
)

val cmd = CommandLine(MyHelpCommand())
Expand Down
47 changes: 47 additions & 0 deletions src/main/kotlin/cz/glubo/adventofcode/utils/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,53 @@ data class IVec2(
infix fun tcDistance(other: IVec2) = abs(this.x - other.x) + abs(this.y - other.y)
}

data class IVec3(
val x: Int,
val y: Int,
val z: Int,
) {
operator fun plus(other: IVec3) =
IVec3(
this.x + other.x,
this.y + other.y,
this.z + other.z,
)

operator fun minus(other: IVec3) =
IVec3(
this.x - other.x,
this.y - other.y,
this.z - other.z,
)

operator fun times(scale: Int) =
IVec3(
scale * this.x,
scale * this.y,
scale * this.z,
)

infix fun dot(other: IVec3) =
this.x.toLong() * other.x +
this.y.toLong() * other.y +
this.z.toLong() * other.z

/**
* Calculates the taxicab distance between this vector and the given vector.
*
* The taxicab distance is the sum of the absolute differences of the corresponding coordinates of the vectors.
*
* @param other The vector to calculate the taxicab distance to.
* @return The taxicab distance between this vector and the given vector.
*/
infix fun tcDistance(other: IVec3) = abs(this.x - other.x) + abs(this.y - other.y) + abs(this.z - other.z)

infix fun squareDistance(other: IVec3): Long {
val diff = this - other
return diff dot diff
}
}

enum class FullDirection(
val vector: IVec2,
val char: Char,
Expand Down
120 changes: 117 additions & 3 deletions src/main/kotlin/cz/glubo/adventofcode/y2025/day8/Day8.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,130 @@
package cz.glubo.adventofcode.y2025.day8

import cz.glubo.adventofcode.utils.IVec3
import cz.glubo.adventofcode.utils.input.Input
import io.klogging.noCoLogger
import kotlin.math.roundToLong
import kotlin.math.sqrt

val logger = noCoLogger({}.javaClass.toString())

suspend fun y2025day8part1(input: Input): Long {
class UnionFind(
size: Int,
) {
val parents = MutableList(size) { it }

fun findRoot(x: Int): Int {
val parent = parents[x]
return if (parents[parent] != parent) {
findRoot(parent).also { parents[x] = it }
} else {
parent
}
}

fun markUnion(
x: Int,
y: Int,
) {
val rootX = findRoot(x)
val rootY = findRoot(y)
parents[rootX] = rootY
}

fun sizes(): List<Int> =
parents
.groupBy { findRoot(it) }
.map { (_, it) -> it.size }
}

suspend fun y2025day8part1(
input: Input,
num: Int = 1000,
): Long {
logger.info("year 2025 day 8 part 1")
return 0
val points = mutableListOf<IVec3>()
input.lineFlow().collect { line ->
val (x, y, z) =
line
.split(',')
.map { it.toInt() }
points.add(IVec3(x, y, z))
}

data class Connection(
val i: Int,
val j: Int,
val squareLength: Long,
) {
fun length() = sqrt(squareLength.toDouble()).roundToLong()
}

val allConnections =
points.indices.flatMap { i ->
(i + 1..<points.size).map { j ->
Connection(
i,
j,
points[i] squareDistance points[j],
)
}
}
val chosenConnections =
allConnections
.sortedBy { it.squareLength }
.take(num)
val union = UnionFind(points.size)
chosenConnections.forEach { conn ->
union.markUnion(conn.i, conn.j)
}

return union
.sizes()
.sortedByDescending { it }
.take(3)
.fold(1L) { acc, i -> acc * i }
}

suspend fun y2025day8part2(input: Input): Long {
logger.info("year 2025 day 8 part 2")
return 0
val points = mutableListOf<IVec3>()
input.lineFlow().collect { line ->
val (x, y, z) =
line
.split(',')
.map { it.toInt() }
points.add(IVec3(x, y, z))
}

data class Connection(
val i: Int,
val j: Int,
val squareLength: Long,
) {
fun length() = sqrt(squareLength.toDouble()).roundToLong()
}

val allConnections =
points.indices
.flatMap { i ->
(i + 1..<points.size).map { j ->
Connection(
i,
j,
points[i] squareDistance points[j],
)
}
}.sortedBy { it.squareLength }
val union = UnionFind(points.size)

var lastConnection: Connection
var i = 0
do {
val conn = allConnections[i]
union.markUnion(conn.i, conn.j)
lastConnection = conn
i++
} while (union.sizes().size > 1 && allConnections.indices.contains((i)))

return points[lastConnection.i].x.toLong() * points[lastConnection.j].x.toLong()
}
45 changes: 43 additions & 2 deletions src/test/kotlin/cz/glubo/adventofcode/y2025/day8/Day8Test.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,58 @@ class Day8Test :
y2025day8part1(
TestInput(
"""
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
""".trimIndent(),
),
) shouldBe 0
10,
) shouldBe 40
}

"day8 example part 2 matches" {
y2025day8part2(
TestInput(
"""
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
""".trimIndent(),
),
) shouldBe 0
) shouldBe 25272
}
})
Loading