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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 11 months ago (1 child)

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

  • source
  • hideshow 1 child comment
  • [โ€“] 1 point 11 months ago

    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
    
  • source
  • parent