It's amusing just how similar our solutions are today. The only real issue I had today was not considering both sides of each range and only taking the last part of the range in the sort order.
var ingredientRanges: MutableList<LongRange> = mutableListOf()
var ingredients: MutableList<Long> = mutableListOf()
fun main() {
val input = getInput(5)
parseInput1(input)
var count = 0L
ingredientRanges.sortBy { it.first }
var i = 0
while (i < ingredientRanges.size) {
var j = i + 1
while (j < ingredientRanges.size && doRangesOverlap(ingredientRanges[i], ingredientRanges[j])) {
ingredientRanges[i] = LongRange(ingredientRanges[i].first, max(ingredientRanges[i].last, ingredientRanges[j].last))
j++
}
count += ingredientRanges[i].last - ingredientRanges[i].first + 1
i = j
}
println(count)
}
fun parseInput1(input: String) {
val split = input.split("\n\n")
split[0].lines()
.filter { it.isNotBlank() }
.forEach {
val range = it.split("-")
ingredientRanges.add(LongRange(range[0].toLong(), range[1].toLong()))
}
split[1].lines()
.filter { it.isNotBlank() }
.forEach { ingredients.add(it.toLong()) }
}
fun doRangesOverlap(left: LongRange, right: LongRange): Boolean = right.first in left || right.first - 1 == left.last