Skip to content

Commit b178145

Browse files
committed
Solution 2017-13 (Packet Scanners)
1 parent 59add91 commit b178145

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
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.day13
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
5+
fun main() = PacketScanners().run(1612, 3907994)
6+
7+
class PacketScanners : AdventOfCode<Int>(2017, 13) {
8+
override fun part1(input: List<String>): Int = input
9+
.parseFirewallConfig()
10+
.sumOf(::severity)
11+
12+
private fun severity(layer: ScanningArea): Int =
13+
if (layer.isScannerOnTopInPicosecond(layer.depth)) {
14+
layer.severity()
15+
} else {
16+
0
17+
}
18+
19+
override fun part2(input: List<String>): Int {
20+
val config = input
21+
.parseFirewallConfig()
22+
23+
return generateSequence(0) { it + 1 }
24+
.map { delay ->
25+
delay to config.any { it.isScannerOnTopInPicosecond(it.depth + delay) }
26+
}
27+
.first { !it.second }
28+
.first
29+
}
30+
}
31+
32+
data class ScanningArea(val depth: Int, val range: Int) {
33+
fun isScannerOnTopInPicosecond(ps: Int): Boolean = ps % ((range - 1) * 2) == 0
34+
fun severity() = depth * range
35+
}
36+
37+
fun List<String>.parseFirewallConfig() = map {
38+
val (depth, range) = it.split(": ")
39+
ScanningArea(depth.toInt(), range.toInt())
40+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package de.ronny_h.aoc.year2017.day13
2+
3+
import de.ronny_h.aoc.extensions.asList
4+
import io.kotest.core.spec.style.StringSpec
5+
import io.kotest.data.forAll
6+
import io.kotest.data.row
7+
import io.kotest.matchers.shouldBe
8+
9+
class PacketScannersTest : StringSpec({
10+
11+
val input = """
12+
0: 3
13+
1: 2
14+
4: 4
15+
6: 4
16+
""".asList()
17+
18+
"input can be parsed" {
19+
input.parseFirewallConfig() shouldBe listOf(
20+
ScanningArea(0, 3),
21+
ScanningArea(1, 2),
22+
ScanningArea(4, 4),
23+
ScanningArea(6, 4),
24+
)
25+
}
26+
27+
"scanner is on top of the layer in the specific picosecond" {
28+
forAll(
29+
row(ScanningArea(0, 3), 0, true),
30+
row(ScanningArea(1, 2), 0, true),
31+
row(ScanningArea(4, 4), 0, true),
32+
row(ScanningArea(6, 4), 0, true),
33+
row(ScanningArea(0, 3), 1, false),
34+
row(ScanningArea(1, 2), 1, false),
35+
row(ScanningArea(4, 4), 1, false),
36+
row(ScanningArea(6, 4), 1, false),
37+
row(ScanningArea(0, 3), 2, false),
38+
row(ScanningArea(1, 2), 2, true),
39+
row(ScanningArea(4, 4), 2, false),
40+
row(ScanningArea(6, 4), 2, false),
41+
row(ScanningArea(0, 3), 3, false),
42+
row(ScanningArea(1, 2), 3, false),
43+
row(ScanningArea(4, 4), 3, false),
44+
row(ScanningArea(6, 4), 3, false),
45+
row(ScanningArea(0, 3), 4, true),
46+
row(ScanningArea(1, 2), 4, true),
47+
row(ScanningArea(4, 4), 4, false),
48+
row(ScanningArea(6, 4), 4, false),
49+
) { layer, ps, expected ->
50+
layer.isScannerOnTopInPicosecond(ps) shouldBe expected
51+
}
52+
}
53+
54+
"part 1: the severity of the example trip" {
55+
PacketScanners().part1(input) shouldBe 24
56+
}
57+
58+
"part 2: the fewest number of picoseconds to delay to get through safely" {
59+
PacketScanners().part2(input) shouldBe 10
60+
}
61+
})

0 commit comments

Comments
 (0)