
🔥 매년 12월 1일부터 12월 25일까지 한 문제씩 프로그래밍 퍼즐을 제공하는 사이트다. Eric Wastl이 2015년에 만든 사이트로, 재림절 달력(Advent calendar)을 매일 열어보듯이 크리스마스까지 꾸준히 문제를 해결해나간다는 컨셉이다. 퍼즐은 UTC-5 기준으로 자정, 한국시간으로는 오후 2시에 공개된다.
출처 : 나무위키 - Advent of Code
Advent of Code가 2023년 돌아왔습니다! 25일간 프로그래밍 퍼즐을 풀어봅시다.
Jetbrains는 이번에도 어김없이 Kotlin을 통해 25일간의 AoC에 참가하면 코틀린 독점 상품을 받을 수 있는 기회를 준다고 합니다!
자세한 내용은 코틀린 블로그에 개제된 Tackle Advent of Code 2023 With Kotlin and Win Prizes! 를 참고하세요.
오늘은 네 번째 문제인 Scratchcard 문제를 풀어봤습니다.
간단하게 복권이라고 생각하면 됩니다.
Scratchcard는 외국의 연금 복권 같은 거라고 생각하면 편합니다.
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
| 를 기준으로 왼쪽은 당첨 번호, 오른쪽은 보유 번호입니다.
1개 당첨되면 1점을 주고, 그 이후에 1개 당첨될 때마다 점수가 2배씩 늘어납니다.
1개 당첨되면 1점을 주고, 그 이후에 1개씩 당첨될 때마다 점수가 2배 늘어난다?
즉 2의 제곱 수입니다. 2^(당첨 개수 - 1)
| 를 기준으로 왼쪽 리스트와 오른쪽 리스트를 가져오고 합친 이후, 중복을 제거한 리스트와 사이즈의 차를 가져옵니다. 이 값이 당첨된 개수입니다.
그 이후 2의 제곱 수 로직에 넣어 값을 도출합니다.
fun part1(input: List<String>): Int {
var sum = 0
input.forEach { str ->
val regex = "\\d+".toRegex()
val list = str.substringAfter(":").split("|").map {
regex.findAll(it).toList().map { it.value.toInt() }
}
val winnings = list.first()
val nums = list.last()
val mergeList = winnings + nums
val size = mergeList.size - mergeList.distinct().size
sum += Math.pow(2.0, (size - 1).toDouble()).toInt()
}
return sum
}
Card 1에서 4개가 당첨되면, Card 2~5의 사본을 추가합니다. 즉 당첨된 개수의 다음 카드들을 1장씩 추가합니다. Card 2~5는 2개가 됩니다.
Card 2에서 2개가 당첨되면, 마찬가지로 Card 3~4을 1장씩 추가합니다. 이 때, Card 2는 Card 1에 의해 1개가 추가되었으므로 Card 3~4도 마찬가지로 2장이 추가됩니다.
이를 반복했을 때, 총 카드의 개수가 몇개가 되는지를 도출하는 문제입니다.
fun part2(input: List<String>): Int {
val winCountList = MutableList(size = input.size) { 0 }
input.forEachIndexed { idx, str ->
val regex = "\\d+".toRegex()
val gameList = str.substringAfter(":").split("|").map {
regex.findAll(it).toList().map { it.value.toInt() }
}
val winnings = gameList.first()
val nums = gameList.last()
val mergeList = winnings + nums
winCountList[idx] = mergeList.size - mergeList.distinct().size
}
val cardCountList = MutableList(size = input.size) { 1 }
for (idx in input.indices) {
val winCount = winCountList[idx]
for (i in 0..<winCount) {
val sIdx = idx + i + 1
if (cardCountList.getOrNull(sIdx) != null) {
cardCountList[sIdx] += cardCountList[idx]
}
}
}
return cardCountList.sum()
}
getOrNull 를 이용해 크래시를 방지합니다.🔥 다른 사람들의 풀이는 KotlinLang Slack에 참여하면 확인할 수 있습니다!
오늘 문제는 난이도가 그렇게 높지 않아 다른 사람들의 풀이도 비슷해 생략합니다!