132 lines
4.2 KiB
Kotlin
132 lines
4.2 KiB
Kotlin
package aoc2023
|
|
|
|
import println
|
|
import readInput
|
|
|
|
/*
|
|
--- Day 25: Snowverload ---
|
|
https://adventofcode.com/2023/day/25
|
|
*/
|
|
fun main() {
|
|
|
|
val inlineTestInput = """
|
|
jqt: rhn xhk nvd
|
|
rsh: frs pzl lsr
|
|
xhk: hfx
|
|
cmg: qnr nvd lhk bvb
|
|
rhn: xhk bvb hfx
|
|
bvb: xhk hfx
|
|
pzl: lsr hfx nvd
|
|
qnr: nvd
|
|
ntq: jqt hfx bvb xhk
|
|
nvd: lhk
|
|
lsr: lhk
|
|
rzs: qnr cmg lsr rsh
|
|
frs: qnr lhk lsr
|
|
"""
|
|
|
|
data class Node(val id: String, val children: MutableSet<Node> = HashSet(), val orgNodes: MutableSet<Node> = HashSet()) {
|
|
override fun equals(other: Any?): Boolean {
|
|
if (this === other) return true
|
|
if (javaClass != other?.javaClass) return false
|
|
|
|
other as Node
|
|
|
|
return id == other.id
|
|
}
|
|
|
|
override fun hashCode(): Int {
|
|
return id.hashCode()
|
|
}
|
|
|
|
override fun toString(): String {
|
|
return "Node(id='$id', children=${children.joinToString { it.id }})"
|
|
}
|
|
}
|
|
|
|
fun connectedSize(rootNode: Node): Int {
|
|
val visited = HashSet<Node>()
|
|
val queue = ArrayDeque<Node>()
|
|
queue.add(rootNode)
|
|
while (queue.isNotEmpty()) {
|
|
val n = queue.removeFirst()
|
|
visited.add(n)
|
|
n.children.forEach { if (!visited.contains(it)) queue.add(it) }
|
|
}
|
|
return visited.size
|
|
}
|
|
|
|
fun part1(input: List<String>): Int {
|
|
val nodeMap = HashMap<String, Node>()
|
|
for (i in input) {
|
|
val (from, to) = i.split(": ")
|
|
val tos = to.split(" ")
|
|
val fromNode = nodeMap.computeIfAbsent(from) { Node(from) }
|
|
val toNodes = tos.map { nodeMap.computeIfAbsent(it) { Node(it) } }
|
|
fromNode.children.addAll(toNodes)
|
|
toNodes.forEach { it.children.add(fromNode) }
|
|
}
|
|
|
|
nodeMap["vps"]!!.children.remove(nodeMap["pzc"])
|
|
nodeMap["pzc"]!!.children.remove(nodeMap["vps"])
|
|
nodeMap["xvk"]!!.children.remove(nodeMap["sgc"])
|
|
nodeMap["sgc"]!!.children.remove(nodeMap["xvk"])
|
|
nodeMap["dph"]!!.children.remove(nodeMap["cvx"])
|
|
nodeMap["cvx"]!!.children.remove(nodeMap["dph"])
|
|
|
|
val res = connectedSize(nodeMap["vps"]!!) * connectedSize(nodeMap["pzc"]!!)
|
|
|
|
// val edges = nodeMap.values.map { s -> s.children.map { t -> s to t } }.flatten()
|
|
//
|
|
// val nodes = nodeMap.values.toMutableList()
|
|
// while (nodes.size > 2) {
|
|
// val n1 = nodes[(Math.random() * nodes.size).toInt().coerceAtMost(nodes.lastIndex)]
|
|
// val n2 = n1.children.keys.toList()[(Math.random() * n1.children.size).toInt().coerceAtMost(n1.children.size - 1)]
|
|
// val superNode = Node(n1.id + "-" + n2.id)
|
|
// if (n1.orgNodes.isEmpty()) {
|
|
// superNode.orgNodes.add(Node(n1.id, children = HashMap(n1.children)))
|
|
// } else {
|
|
// superNode.orgNodes.addAll(n1.orgNodes)
|
|
// }
|
|
// if (n2.orgNodes.isEmpty()) {
|
|
// superNode.orgNodes.add(Node(n2.id, children = HashMap(n2.children)))
|
|
// } else {
|
|
// superNode.orgNodes.addAll(n2.orgNodes)
|
|
// }
|
|
// n1.children.filter { it.key != n2 }
|
|
// .forEach { }
|
|
// superNode.children.addAll(n1.children.filter { it != n2 })
|
|
// superNode.children.addAll(n2.children.filter { it != n1 })
|
|
//
|
|
// superNode.children.forEach {
|
|
// it.children.remove(n1)
|
|
// it.children.remove(n2)
|
|
// it.children.add(superNode)
|
|
// }
|
|
// nodes.remove(n1)
|
|
// nodes.remove(n2)
|
|
// nodes.add(superNode)
|
|
// }
|
|
|
|
return res
|
|
}
|
|
|
|
fun part2(input: List<String>): Int {
|
|
return 0
|
|
}
|
|
|
|
// test if implementation meets criteria from the description, like:
|
|
val testInput = inlineTestInput.trim().reader().readLines()
|
|
//val testInput = readInput("aoc2023/Day25_test")
|
|
//val testInputPart1Result = part1(testInput)
|
|
//println("Part 1 Test: $testInputPart1Result")
|
|
val testInputPart2Result = part2(testInput)
|
|
println("Part 2 Test: $testInputPart2Result")
|
|
//check(testInputPart1Result == 0)
|
|
check(testInputPart2Result == 0)
|
|
|
|
val input = readInput("aoc2023/Day25")
|
|
part1(input).println()
|
|
part2(input).println()
|
|
}
|