generated from Jadarma/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathY2016D07.kt
84 lines (71 loc) · 3.56 KB
/
Y2016D07.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package aockt.y2016
import io.github.jadarma.aockt.core.Solution
object Y2016D07 : Solution {
/** A valid IPv7 address. */
private data class IPv7Address(val value: String) {
/** All sequences in the address, in order. */
val sequences: List<String> = buildList {
// Note: This initialization is just for show, correctly parsing the addresses and reporting errors.
// However, since the problem input is always valid, this can be replaced with just for brevity:
//
// ```kotlin
// val sequences = value.split(Regex("""[\[\]]"""))
// ```
val sequence = StringBuilder()
var insideSequence = false
val emitSequence = {
val net = sequence.toString()
sequence.clear()
require(net.isNotEmpty()) { "Invalid address; sequences cannot be empty." }
add(net)
}
value.forEach { c ->
when (c) {
'[' -> {
require(!insideSequence) { "Invalid address; sequences cannot be nested." }
insideSequence = true
emitSequence()
}
']' -> {
require(insideSequence) { "Invalid address; unmatched closing bracket." }
insideSequence = false
emitSequence()
}
else -> {
require(c in 'a'..'z') { "Invalid address; illegal character." }
sequence.append(c)
}
}
}
require(!insideSequence) { "Invalid address; unmatched opening bracket." }
emitSequence()
}
/** Returns only the superNet sequences of the address (outside of brackets). */
val superNetSequences: List<String> get() = sequences.filterIndexed { index, _ -> index % 2 == 0 }
/** Returns only the hyperNet sequences of the address (inside of brackets). */
val hyperNetSequences: List<String> get() = sequences.filterIndexed { index, _ -> index % 2 == 1 }
/** Whether this address supports Transport-Layer Snooping. */
val supportsTls: Boolean
get() = superNetSequences.any { it.findABBAs().isNotEmpty() } &&
hyperNetSequences.all { it.findABBAs().isEmpty() }
/** Whether this address supports Super-Secret Listening. */
val supportsSsl: Boolean
get() {
val aba = superNetSequences.flatMap { it.findABAs() }.toSet()
val bab = hyperNetSequences.flatMap { it.findABAs() }.toSet()
return aba.any { a -> bab.any { b -> a[0] == b[1] && a[1] == b[0] } }
}
/** Returns a set of all Autonomous Bridge Bypass Annotation contained in this sequence. */
private fun String.findABBAs() =
windowedSequence(4)
.filter { it[0] != it[1] && it[0] == it[3] && it[1] == it[2] }
.toSet()
/** Returns a set of all Area-Broadcast Accessors and Byte Allocation Blocks contained in this sequence. */
private fun String.findABAs(): Set<String> =
windowedSequence(3)
.filter { it[0] != it[1] && it[0] == it[2] }
.toSet()
}
override fun partOne(input: String) = input.lineSequence().map(::IPv7Address).count { it.supportsTls }
override fun partTwo(input: String) = input.lineSequence().map(::IPv7Address).count { it.supportsSsl }
}