diff --git a/src/aoc2025/Day02.kt b/src/aoc2025/Day02.kt new file mode 100644 index 0000000..b1e32db --- /dev/null +++ b/src/aoc2025/Day02.kt @@ -0,0 +1,86 @@ +package aoc2025 + +import println +import readInput +import kotlin.math.log10 + +/* +--- Day 2: Gift Shop --- +https://adventofcode.com/2025/day/2 +*/ +fun main() { + + val inlineTestInput = """ +11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124 +""" + + fun part1(input: List): Long { + val ranges = input[0].split(",").map { it.split("-").map { it.toLong() } } + val powTenTable = generateSequence(1L) { it * 10L }.take(20).toList().toLongArray() + var sum = 0L + for ((low, high) in ranges) { + var i = low + while (i <= high) { + val numDigits = log10(i.toDouble()).toInt() + 1 + if (numDigits % 2 == 1) { + i = powTenTable[numDigits] + } else { + val firstHalf = i / powTenTable[numDigits / 2] + val matchNum = firstHalf * powTenTable[numDigits / 2] + firstHalf + if (matchNum in low..high) { + sum += matchNum + } + i = (firstHalf + 1) * powTenTable[numDigits / 2] + } + } + } + return sum + } + + fun part2(input: List): Long { + val ranges = input[0].split(",").map { it.split("-").map { it.toLong() } } + val powTenTable = generateSequence(1L) { it * 10L }.take(20).toList().toLongArray() + val mulElevenArray = arrayOf( + generateSequence(1L) { it * 10L + 1L }.take(20).toList().toLongArray(), + generateSequence(1L) { it * 100L + 1L }.take(10).toList().toLongArray(), + generateSequence(1L) { it * 1000L + 1L }.take(7).toList().toLongArray(), + generateSequence(1L) { it * 10000L + 1L }.take(5).toList().toLongArray(), + generateSequence(1L) { it * 100000L + 1L }.take(4).toList().toLongArray(), + generateSequence(1L) { it * 1000000L + 1L }.take(4).toList().toLongArray(), + generateSequence(1L) { it * 10000000L + 1L }.take(3).toList().toLongArray(), + generateSequence(1L) { it * 100000000L + 1L }.take(3).toList().toLongArray(), + ) + + var sum = 0L + for ((low, high) in ranges) { + var i = low + val illegalSet = mutableSetOf() + while (i <= high) { + val numDigits = log10(i.toDouble()).toInt() + 1 + for (n in 1..numDigits / 2) { + val firstBit = i / powTenTable[numDigits - n] + val matchNum = firstBit * mulElevenArray[n - 1][(numDigits - 1) / n] + illegalSet.add(matchNum) + } + val firstHalf = i / powTenTable[numDigits / 2] + i = (firstHalf + 1) * powTenTable[numDigits / 2] + } + sum += illegalSet.filter { it in low..high }.sum() + } + return sum + } + + // test if implementation meets criteria from the description, like: + val testInput = inlineTestInput.trim().reader().readLines() + //val testInput = readInput("aoc2025/Day02_test") + val testInputPart1Result = part1(testInput) + println("Part 1 Test: $testInputPart1Result") + val testInputPart2Result = part2(testInput) + println("Part 2 Test: $testInputPart2Result") + check(testInputPart1Result == 1227775554L) + check(testInputPart2Result == 4174379265L) + + val input = readInput("aoc2025/Day02") + part1(input).println() + part2(input).println() +}