Day 2: Gift Shop

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

    Kotlin

    got up early for this one, sadly it took me over 30 minutes to realize, that my code at the time was also considering a single digit valid .-.

    also still pretty scuffed, but hey it works:

    Solution
    class Day02 : Puzzle {
    
        val ids = mutableSetOf<String>()
    
        override fun readFile() {
            val input = readInputFromFile("src/main/resources/a2025/day02.txt")
            ids.addAll(
                input.replace("\n", "")
                    .split(",")
                    .map { it.split("-") }
                    .map(this::buildList)
                    .flatten()
            )
        }
    
        private fun buildList(rangeList: List<String>): List<String> {
            val start = rangeList[0].toLong()
            val end = rangeList[1].toLong()
            val ids = mutableListOf<String>()
            for (i in start..end) {
                ids.add(i.toString())
            }
            return ids
        }
    
        override fun solvePartOne(): String {
            return ids.filter(this::idNotValid)
                .sumOf(String::toLong).toString()
        }
    
        override fun solvePartTwo(): String {
            return ids.filter { idNotValid(it, true) }
                .sumOf(String::toLong).toString()
        }
    
        private fun idNotValid(id: String, multipleSplits: Boolean = false): Boolean {
            val length = id.length
    
            // try all splits
            var split = 2
            while (split <= length) {
                if (length % split == 0) {
                    val splits = mutableListOf<String>()
                    var beg = 0
                    var end = length / split
                    val step = end
                    for (i in 0..<split) {
                        splits.add(id.substring(beg, end))
                        beg += step
                        end += step
                    }
                    if (splits.all { it == splits[0] }) return true
                }
                if (multipleSplits) {
                    split++
                } else {
                    break
                }
            }
            return false
        }
    }
    

    full code on Codeberg

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

      My part 2 Kotlin solution:

      val factors = intArrayOf(2, 3, 5, 7)
      
      fun main() {
          var total = 0L
          val input = getInput(2)
          val ranges = parseInput1(input)
          ranges.forEach {
              val start = it.first.toLong()
              val end = it.second.toLong()
              for (id in start..end) {
                  val idString = id.toString()
                  if (isIdInvalid2(idString)) {
                      total += id
                  }
              }
          }
          println(total)
      }
      
      fun parseInput1(input: String): List<Pair<String, String>> {
          return input.split(",")
              .filter { it.isNotBlank() }
              .map {
                  val secondSplit = it.split("-")
                  secondSplit.first().trim() to secondSplit.last().trim()
              }
      }
      
      fun isIdInvalid2(id: String): Boolean {
          for (factor in factors) {
              if (id.length % factor == 0) {
                  val gap = id.length / factor
                  var areAllMatching = true
                  for (i in 0..<gap) {
                      val end = (factor - 1) * gap + i
                      if (!areCharactersTheSame(id, gap, i, end)) {
                          areAllMatching = false
                          break
                      }
                  }
                  if (areAllMatching) {
                      return true
                  }
              }
          }
          return false
      }
      
      fun areCharactersTheSame(string: String, gap: Int, start: Int, end: Int): Boolean {
          val character = string[start]
          for (i in start + gap..end step gap) {
              if (character != string[i]) {
                  return false
              }
          }
          return true
      }
      

      I didn’t look closely enough at the input to know how big an entire list of IDs would be huge or not. But I assumed it was. So instead I just did ranges as Pairs.

      I also only considered the prime factors up to 7, because there weren’t any IDs that needed any higher.

      Edit: I also worried that a brute force solution might be slow, but being day 2, I might have been a little too worried about that. The main algorithm ran in 68ms.