71 lines
2.3 KiB
Kotlin
71 lines
2.3 KiB
Kotlin
package aoc2023
|
|
|
|
import println
|
|
import readInput
|
|
import splitInts
|
|
|
|
/*
|
|
--- Day 4: Scratchcards ---
|
|
https://adventofcode.com/2023/day/4
|
|
*/
|
|
fun main() {
|
|
|
|
val inlineTestInput = """
|
|
Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
|
|
Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
|
|
Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1
|
|
Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
|
|
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
|
|
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11
|
|
"""
|
|
|
|
fun part1(input: List<String>): Int {
|
|
return input.map {
|
|
"Card +(\\d+): (.*)".toRegex().matchEntire(it)?.destructured
|
|
?.let { (id, game) ->
|
|
val (wins, numbers) = game.split(" | ")
|
|
val winSet = wins.splitInts().toSet()
|
|
val numberSet = numbers.splitInts().toSet()
|
|
val matches = winSet.intersect(numberSet)
|
|
1 shl (matches.size - 1)
|
|
}
|
|
}.sumOf { it!! }
|
|
}
|
|
|
|
fun part2(input: List<String>): Int {
|
|
val winTable = input.map {
|
|
"Card +(\\d+): (.*)".toRegex().matchEntire(it)?.destructured
|
|
?.let { (id, game) ->
|
|
val (wins, numbers) = game.split(" | ")
|
|
val winSet = wins.splitInts().toSet()
|
|
val numberSet = numbers.splitInts().toSet()
|
|
val matches = winSet.intersect(numberSet)
|
|
matches.size
|
|
}!!
|
|
}.toList()
|
|
val accTable = IntArray(winTable.size)
|
|
for (i in winTable.indices.reversed()) {
|
|
var sum = 1
|
|
for (j in i + 1 until (i + winTable[i] + 1).coerceAtMost(winTable.size)) {
|
|
sum += accTable[j]
|
|
}
|
|
accTable[i] = sum
|
|
}
|
|
return accTable.sum()
|
|
}
|
|
|
|
// test if implementation meets criteria from the description, like:
|
|
val testInput = inlineTestInput.trim().reader().readLines()
|
|
//val testInput = readInput("aoc2023/Day04_test")
|
|
val testInputPart1Result = part1(testInput)
|
|
println("Part 1 Test: $testInputPart1Result")
|
|
val testInputPart2Result = part2(testInput)
|
|
println("Part 2 Test: $testInputPart2Result")
|
|
check(testInputPart1Result == 13)
|
|
check(testInputPart2Result == 30)
|
|
|
|
val input = readInput("aoc2023/Day04")
|
|
part1(input).println()
|
|
part2(input).println()
|
|
}
|