This commit is contained in:
Chris Hodges 2024-12-23 07:45:35 +01:00
parent e222975b2a
commit 277bc6cc8e

111
src/aoc2024/Day23.kt Normal file
View File

@ -0,0 +1,111 @@
package aoc2024
import println
import readInput
/*
--- Day 23: LAN Party ---
https://adventofcode.com/2024/day/23
*/
fun main() {
val inlineTestInput = """
kh-tc
qp-kh
de-cg
ka-co
yn-aq
qp-ub
cg-tb
vc-aq
tb-ka
wh-tc
yn-cg
kh-ub
ta-co
de-co
tc-td
tb-wq
wh-td
ta-ka
td-qp
aq-cg
wq-ub
ub-vc
de-ta
wq-aq
wq-vc
wh-yn
ka-de
kh-ta
co-tc
wh-qp
tb-vc
td-yn
"""
fun part1(input: List<String>): Int {
val nodes = HashMap<String, MutableSet<String>>()
for (i in input) {
val (n1, n2) = i.split("-")
val e1 = nodes.getOrPut(n1) { HashSet() }
val e2 = nodes.getOrPut(n2) { HashSet() }
e1.add(n2)
e2.add(n1)
}
val threesomes = nodes
.flatMap {
it.value.flatMap { i1 ->
it.value.filter { it != i1 }.mapNotNull { i2 ->
if (nodes[i1]!!.contains(it.key) && nodes[i2]!!.contains(it.key) && nodes[i1]!!.contains(i2)) sortedSetOf(it.key, i1, i2) else null
}
}
}.map { it.joinToString("-", prefix = "-") }.distinct()
return threesomes.count { it.contains("-t") }
}
fun bronKerbosch(nodes: Map<String, Set<String>>, r: Set<String>, p: Set<String>, x: MutableSet<String>): Set<String> {
if (p.isEmpty() && x.isEmpty()) {
return r
}
var maxClique = emptySet<String>()
val ptmp = p.toMutableSet()
for (v in p) {
val res = bronKerbosch(nodes, r.plus(v), ptmp.intersect(nodes[v]!!), x.intersect(nodes[v]!!).toMutableSet())
if (res.size > maxClique.size) {
maxClique = res
}
ptmp.remove(v)
x.add(v)
}
return maxClique
}
fun part2(input: List<String>): String {
val nodes = HashMap<String, MutableSet<String>>()
for (i in input) {
val (n1, n2) = i.split("-")
val e1 = nodes.getOrPut(n1) { HashSet() }
val e2 = nodes.getOrPut(n2) { HashSet() }
e1.add(n2)
e2.add(n1)
}
val largestSet = bronKerbosch(nodes, emptySet(), nodes.keys, mutableSetOf())
return largestSet.asSequence().sorted().joinToString(",")
}
// test if implementation meets criteria from the description, like:
val testInput = inlineTestInput.trim().reader().readLines()
//val testInput = readInput("aoc2024/Day23_test")
val testInputPart1Result = part1(testInput)
println("Part 1 Test: $testInputPart1Result")
val testInputPart2Result = part2(testInput)
println("Part 2 Test: $testInputPart2Result")
check(testInputPart1Result == 7)
check(testInputPart2Result == "co,de,ka,ta")
val input = readInput("aoc2024/Day23")
part1(input).println()
part2(input).println()
}