My part 2 Kotlin solution:
val factors = intArrayOf(2, 3, 5, 7)
fun main() {
var total = 0L
val input = getInput(2)
val ranges = parseInput1(input)
ranges.forEach {
val start = it.first.toLong()
val end = it.second.toLong()
for (id in start..end) {
val idString = id.toString()
if (isIdInvalid2(idString)) {
total += id
}
}
}
println(total)
}
fun parseInput1(input: String): List<Pair<String, String>> {
return input.split(",")
.filter { it.isNotBlank() }
.map {
val secondSplit = it.split("-")
secondSplit.first().trim() to secondSplit.last().trim()
}
}
fun isIdInvalid2(id: String): Boolean {
for (factor in factors) {
if (id.length % factor == 0) {
val gap = id.length / factor
var areAllMatching = true
for (i in 0..<gap) {
val end = (factor - 1) * gap + i
if (!areCharactersTheSame(id, gap, i, end)) {
areAllMatching = false
break
}
}
if (areAllMatching) {
return true
}
}
}
return false
}
fun areCharactersTheSame(string: String, gap: Int, start: Int, end: Int): Boolean {
val character = string[start]
for (i in start + gap..end step gap) {
if (character != string[i]) {
return false
}
}
return true
}
I didn't look closely enough at the input to know how big an entire list of IDs would be huge or not. But I assumed it was. So instead I just did ranges as Pairs.
I also only considered the prime factors up to 7, because there weren't any IDs that needed any higher.
Edit: I also worried that a brute force solution might be slow, but being day 2, I might have been a little too worried about that. The main algorithm ran in 68ms.