generated from Jadarma/advent-of-code-kotlin-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathY2015D11.kt
35 lines (28 loc) · 1.35 KB
/
Y2015D11.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
package aockt.y2015
import io.github.jadarma.aockt.core.Solution
object Y2015D11 : Solution {
// Predicates for a valid password
private val illegalCharacterRule = Regex("""[iol]""")
private val doublePairRule = Regex("""(.)\1(?!.*\1.*$).*(.)\2""")
private val passwordValidationRules: List<(String) -> Boolean> = listOf(
{ !it.contains(illegalCharacterRule) },
{ it.contains(doublePairRule) },
{ it.windowed(3).any { c -> c[0] + 1 == c[1] && c[1] + 1 == c[2] } },
)
/** Returns the next password by incrementing and handling letter overflows. */
private fun String.incrementPassword(): String {
val chars = toCharArray()
for (i in chars.indices.reversed()) {
chars[i] = if (chars[i] == 'z') 'a' else chars[i] + 1
if (chars[i] != 'a') break
}
return String(chars)
}
/** Generates valid passwords in ascending order starting from the [seed], but excluding it even if valid. */
private fun passwordSequence(seed: String) =
generateSequence(seed) { it.incrementPassword() }
.drop(1)
.filter { candidate -> passwordValidationRules.all { rule -> rule(candidate) } }
override fun partOne(input: String) = passwordSequence(input).first()
override fun partTwo(input: String) = passwordSequence(input).drop(1).first()
}