Skip to content

Commit b3ed1ba

Browse files
committed
Solution Day 23, part two (LAN Party)
1 parent 151561b commit b3ed1ba

File tree

2 files changed

+87
-19
lines changed

2 files changed

+87
-19
lines changed

src/main/kotlin/de/ronny_h/aoc/year24/day23/LANParty.kt

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,25 @@ package de.ronny_h.aoc.year24.day23
22

33
import de.ronny_h.aoc.AdventOfCode
44

5-
fun main() = LANParty().run(1240, 0)
5+
fun main() = LANParty().run("1240", "am,aq,by,ge,gf,ie,mr,mt,rw,sn,te,yi,zb")
66

7-
class LANParty : AdventOfCode<Int>(2024, 23) {
7+
class LANParty : AdventOfCode<String>(2024, 23) {
88

9-
override fun part1(input: List<String>): Int = Network(input)
9+
override fun part1(input: List<String>): String = Network(input)
1010
.searchForLANPartiesWithThreeComputers()
11-
.filter { set -> set.any { it.startsWith("t") } }.size
11+
.filter { set -> set.any { it.startsWith("t") } }
12+
.size
13+
.toString()
1214

13-
override fun part2(input: List<String>): Int {
14-
TODO("Not yet implemented")
15-
}
15+
override fun part2(input: List<String>): String = Network(input)
16+
.sortedConnectionSets()
17+
.findLargestIntersection()
18+
.sorted()
19+
.joinToString(",")
1620
}
1721

1822
class Network(input: List<String>) {
19-
// from one computer to all others it is directly connected to
23+
// a map entry for computer `c` contains all other computers that `c` is directly connected to
2024
private val connections: Map<String, Set<String>>
2125

2226
init {
@@ -33,14 +37,38 @@ class Network(input: List<String>) {
3337
val triples = mutableSetOf<Set<String>>()
3438
connections.forEach { (computer, neighbors) ->
3539
neighbors.forEach { neighbor ->
36-
val otherNeighborsNeighbors = connections.getValue(neighbor).filterNot { it == computer }
40+
val neighborsOtherNeighbors = connections.getValue(neighbor).filterNot { it == computer }
3741
val neighborsWithBacklinkToComputer =
38-
otherNeighborsNeighbors.filter { connections.getValue(it).contains(computer) }
42+
neighborsOtherNeighbors.filter { connections.getValue(it).contains(computer) }
3943
neighborsWithBacklinkToComputer.forEach {
4044
triples.add(setOf(computer, neighbor, it))
4145
}
4246
}
4347
}
4448
return triples
4549
}
50+
51+
fun sortedConnectionSets() = connections
52+
.map { (computer, neighbors) -> neighbors + computer }
53+
.sortedBy { -it.size }
54+
}
55+
56+
fun List<Set<String>>.findLargestIntersection(): Set<String> {
57+
// precondition: `this` is sorted in decreasing order by size
58+
var largestIntersection = emptySet<String>()
59+
for ((i, s1) in this.withIndex()) {
60+
for ((j, s2) in this.withIndex()) {
61+
if (i == j) continue
62+
if (s2.size < largestIntersection.size) {
63+
return largestIntersection
64+
}
65+
val intersection = s1 intersect s2
66+
if (intersection.size > largestIntersection.size) {
67+
if (this.count { it.containsAll(intersection) } == intersection.size) {
68+
largestIntersection = intersection
69+
}
70+
}
71+
}
72+
}
73+
return largestIntersection
4674
}

src/test/kotlin/de/ronny_h/aoc/year24/day23/LANPartyTest.kt

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,67 @@ class LANPartyTest : StringSpec({
4141
td-yn
4242
""".asList()
4343

44-
"in a simple network with three computers, a LAN party of these three is found" {
45-
val smallInput = """
44+
/*
45+
a: b,c -> a,b,c
46+
b: a,c,d -> a,b,c,d
47+
c: a,b,e -> a,b,c, e
48+
d: b,e -> b, d,e
49+
e: c,d -> c,d,e
50+
*/
51+
val smallInput = """
4652
a-b
53+
b-d
4754
b-c
55+
c-e
4856
c-a
57+
d-e
4958
""".asList()
50-
Network(smallInput).searchForLANPartiesWithThreeComputers() shouldBe setOf(setOf("a", "b", "c"))
51-
}
5259

53-
"in a simple network with five computers, a LAN party of three is found" {
54-
val smallInput = """
60+
/*
61+
a: b,c -> a,b,c
62+
b: a,c -> a,b,c
63+
c: a,b -> a,b,c
64+
*/
65+
"in a simple network with three computers, a LAN party of these three is found" {
66+
val minimalInput = """
5567
a-b
56-
b-d
5768
b-c
58-
c-e
5969
c-a
6070
""".asList()
71+
Network(minimalInput).searchForLANPartiesWithThreeComputers() shouldBe setOf(setOf("a", "b", "c"))
72+
}
73+
74+
"in a simple network with five computers, a LAN party of three is found" {
6175
Network(smallInput).searchForLANPartiesWithThreeComputers() shouldBe setOf(setOf("a", "b", "c"))
6276
}
6377

6478
"part1: For all sets of three inter-connected computers, the number containing a computer starting with t" {
65-
LANParty().part1(input) shouldBe 7
79+
LANParty().part1(input) shouldBe "7"
80+
}
81+
82+
"sortedConnectionSets() sorts the sets of computers directly connected to one of them descendant by length" {
83+
Network(smallInput).sortedConnectionSets() shouldBe listOf(
84+
setOf("a","b","c","d"),
85+
setOf("a","b","c","e"),
86+
setOf("a","b","c"),
87+
setOf("b","d","e"),
88+
setOf("c","d","e"),
89+
)
90+
}
91+
92+
"findLargestIntersection() finds the largest intersection that exists at least its length times over all sets" {
93+
listOf(
94+
setOf("a","d","e","f"), // is largest intersection but occurs only twice, not four times
95+
setOf("a","d","e","f"),
96+
setOf("a","b","c","d"),
97+
setOf("a","b","c","e"),
98+
setOf("a","b","c"),
99+
setOf("b","d","e"),
100+
setOf("c","d","e"),
101+
).findLargestIntersection() shouldBe setOf("a", "b", "c")
102+
}
103+
104+
"part2: largest set of computers that are all connected to each other, sorted alphabetically" {
105+
LANParty().part2(input) shouldBe "co,de,ka,ta"
66106
}
67107
})

0 commit comments

Comments
 (0)