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
- 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
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
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.