Skip to content

Commit e07c745

Browse files
committed
Solution 2017-24 (Electromagnetic Moat)
1 parent 26ce9e0 commit e07c745

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package de.ronny_h.aoc.year2017.day24
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.collections.filterMaxBy
5+
6+
fun main() = ElectromagneticMoat().run(1906, 1824)
7+
8+
class ElectromagneticMoat : AdventOfCode<Int>(2017, 24) {
9+
override fun part1(input: List<String>): Int {
10+
return buildStrongestBridge(0, 0, input.parseComponents())
11+
}
12+
13+
override fun part2(input: List<String>): Int {
14+
return buildLongestBridge(0, emptyList(), input.parseComponents()).strength()
15+
}
16+
}
17+
18+
fun List<String>.parseComponents() = map {
19+
val (port1, port2) = it.split("/")
20+
Component(port1.toInt(), port2.toInt())
21+
}
22+
23+
data class Component(private val port1: Int, private val port2: Int) {
24+
fun hasPort(port: Int): Boolean = port1 == port || port2 == port
25+
fun other(port: Int) = if (port1 != port) port1 else port2
26+
fun strength() = port1 + port2
27+
}
28+
29+
private fun List<Component>.strength() = sumOf(Component::strength)
30+
31+
fun buildStrongestBridge(lastPort: Int, strength: Int, remaining: List<Component>): Int {
32+
if (remaining.isEmpty()) {
33+
return strength
34+
}
35+
36+
val matching = remaining.filter { it.hasPort(lastPort) }
37+
if (matching.isEmpty()) {
38+
return strength
39+
}
40+
41+
return matching.maxOf { buildStrongestBridge(it.other(lastPort), strength + it.strength(), remaining - it) }
42+
}
43+
44+
fun buildLongestBridge(lastPort: Int, bridge: List<Component>, remaining: List<Component>): List<Component> {
45+
if (remaining.isEmpty()) {
46+
return bridge
47+
}
48+
49+
val matching = remaining.filter { it.hasPort(lastPort) }
50+
if (matching.isEmpty()) {
51+
return bridge
52+
}
53+
54+
return matching
55+
.map { buildLongestBridge(it.other(lastPort), bridge + it, remaining - it) }
56+
.filterMaxBy(List<Component>::size)
57+
.maxBy(List<Component>::strength)
58+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package de.ronny_h.aoc.year2017.day24
2+
3+
import de.ronny_h.aoc.extensions.asList
4+
import io.kotest.core.spec.style.StringSpec
5+
import io.kotest.matchers.shouldBe
6+
7+
class ElectromagneticMoatTest : StringSpec({
8+
9+
val input = """
10+
0/2
11+
2/2
12+
2/3
13+
3/4
14+
3/5
15+
0/1
16+
10/1
17+
9/10
18+
""".asList()
19+
20+
"components can be parsed" {
21+
input.parseComponents() shouldBe listOf(
22+
Component(0, 2),
23+
Component(2, 2),
24+
Component(2, 3),
25+
Component(3, 4),
26+
Component(3, 5),
27+
Component(0, 1),
28+
Component(10, 1),
29+
Component(9, 10),
30+
)
31+
}
32+
33+
"part 1: the strongest bridge's strength is 31" {
34+
ElectromagneticMoat().part1(input) shouldBe 31
35+
}
36+
37+
"part 2: the longest bridge's strength is 19" {
38+
ElectromagneticMoat().part2(input) shouldBe 19
39+
}
40+
})

0 commit comments

Comments
 (0)