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

  • eco_game@discuss.tchncs.de
    link
    fedilink
    arrow-up
    2
    ·
    5 days ago

    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

    • chunkystyles@sopuli.xyz
      link
      fedilink
      English
      arrow-up
      1
      ·
      4 days 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