Day 3: Lobby

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
    4
    ·
    3 days ago

    Kotlin

    First day this year where I am very happy with my solution. Just super simple, recursive string building.

    Solution
    class Day03 : Puzzle {
    
        val banks = mutableListOf<String>()
    
        override fun readFile() {
            val input = readInputFromFile("src/main/resources/a2025/day03.txt")
            banks.addAll(input.lines().filter(String::isNotBlank))
        }
    
        override fun solvePartOne(): String {
            val sum = banks.map { buildNumber(it, 2) }.sumOf { it.toLong() }
            return sum.toString()
        }
    
        override fun solvePartTwo(): String {
            val sum = banks.map { buildNumber(it, 12) }.sumOf { it.toLong() }
            return sum.toString()
        }
    
        private fun buildNumber(bank: String, remainingDigits: Int): String {
            if (remainingDigits <= 0) return ""
            val current = bank.dropLast(remainingDigits - 1)
            val max = current.max()
            return max + buildNumber(bank.split(max, limit = 2)[1], remainingDigits - 1)
        }
    }
    

    full code on Codeberg

    • chunkystyles@sopuli.xyz
      link
      fedilink
      English
      arrow-up
      2
      ·
      3 days ago

      Today was interesting. My first thought was that part 2 would be a lot more complex at first glance. But I realized that my solution for part 1 worked almost out of the box for part 2.

      I was also pleased to see that the algorithm ran in 1ms, which was a good deal faster than just parsing the input.

      fun main() {
          val input = getInput(3)
          val banks = parseInput(input)
          var total = 0L
          banks.forEach { bank ->
              var location = 0
              var joltage = 0L
              for (power in 11 downTo 0) {
                  val multiplier = 10.toDouble().pow(power).toLong()
                  val batteryLocation = findBattery(bank, location, bank.size - power - 1)
                  val battery = bank[batteryLocation]
                  location = batteryLocation + 1
                  joltage += battery.toLong() * multiplier
              }
              total += joltage
          }
          println(total)
      }
      
      fun parseInput(input: String): List<List<Int>> = input
          .split("\n")
          .filter { it.isNotBlank() }
          .map { it.toCharArray() }
          .map { it.map { digit -> digit.digitToInt() } }
      
      fun findBattery(bank: List<Int>, start: Int, end: Int): Int {
          var max = 0
          var location = 0
          for (i in start..end) {
              val battery = bank[i]
              if (battery > max) {
                  max = battery
                  location = i
                  if (battery == 9) {
                      break
                  }
              }
          }
          return location
      }
      
        • chunkystyles@sopuli.xyz
          link
          fedilink
          English
          arrow-up
          2
          arrow-down
          1
          ·
          3 days ago

          I was curious, so I ran yours and it is only like 3-4ms slower. I was honestly surprised it was that close.

          Just goes to show that we’re often wrong when estimating and the only real way to know is to benchmark.

          • Deebster@programming.dev
            link
            fedilink
            arrow-up
            2
            ·
            3 days ago

            My version used strings as well, and I thought that as I was comparing small integers either way, it made sense to stay in ASCII as the strings were already easy to index, and it meant I could skip parsing input numbers, only needing to parse output numbers so they could be summed.

            I did start with numbers so I could convert it back to compare, but it’s so fast (the whole thing takes 1ms - and that’s reading/parsing the input twice) that it’s almost a micro benchmark.

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

            Yeah, I vaguely remember reading something about how close string splitting is to all the logarithm math in splitting numbers, and since then I’ve just always used strings because that’s way more intuitive to me lol