Day 5: Cafeteria
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465


Kotlin
I first solved the puzzle with my own horrible range-merging algorithm, had quite a few nasty off by one errors. I quickly replaced it with the “normal” merge-algorithm after getting the right solution.
If you really want to see my abomination, it’s still in the commits on my repo.
Solution
class Day05 : Puzzle { val validIds = mutableSetOf<LongRange>() val ids = mutableListOf<Long>() override fun readFile() { val input = readInputFromFile("src/main/resources/a2025/day05.txt") val inputList = input.split("\n\n", limit = 2) validIds.addAll( inputList[0].lines().filter { it.isNotBlank() } .map { it.split("-").map { it.toLong() } } .map { LongRange(it[0], it[1]) } ) ids.addAll(inputList[1].lines().filter { it.isNotBlank() }.map { it.toLong() }) } override fun solvePartOne(): String { return ids.count { id -> validIds.any { id in it } }.toString() } override fun solvePartTwo(): String { val idsSorted = validIds.sortedBy { it.first } val merged = mutableSetOf<LongRange>() var current = idsSorted.first() for (i in 1..<idsSorted.size) { val next = idsSorted[i] if (next.first <= current.last) { current = LongRange(current.first, max(current.last, next.last())) } else { merged.add(current) current = next } } merged.add(current) return merged.sumOf { it.last + 1 - it.first }.toString() } }full code on Codeberg
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