Created
December 22, 2021 11:47
-
-
Save ende76/8af6b17e678fae254779deed4a50d0c0 to your computer and use it in GitHub Desktop.
Kotlin solution for https://adventofcode.com/2021/day/21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private fun readChar(): Char = readString()[0] | |
private fun readChars(): CharArray = readString().toCharArray() | |
private fun readInt(): Int = readLine()!!.toInt() | |
private fun readInts(): List<Int> = readLine()!!.trim().split(" ").map(String::toInt) | |
private fun readLong(): Long = readLine()!!.toLong() | |
private fun readLongs(): List<Long> = readLine()!!.trim().split(" ").map(String::toLong) | |
private fun readString(): String = readLine()!!.trim() | |
private fun readStrings(): List<String> = readLine()!!.trim().split(" ") | |
fun roll(die: Int, dieSides: Int) = Pair(die + (die % dieSides) + (die + 1) % dieSides + 2, (die + 2) % dieSides + 1) | |
fun main() { | |
var rolls = IntArray(10) | |
rolls[0] = 1 | |
for (i in 1..3) { | |
val newRolls = IntArray(10) | |
for ((score, count) in rolls.withIndex()) { | |
if (count == 0) continue | |
for (roll in 1..3) { | |
newRolls[score + roll] += count | |
} | |
} | |
rolls = newRolls | |
} | |
val boardSize = 10 | |
val dieSides = 100 | |
val winningScore = 21 | |
val startPosition1 = readString().split(": ")[1].toInt() | |
val startPosition2 = readString().split(": ")[1].toInt() | |
var state = Array(winningScore + boardSize) { Array(winningScore + boardSize) { Array(boardSize + 1) { LongArray(boardSize + 1) } } } | |
state[0][0][startPosition1][startPosition2] = 1 | |
var done = false | |
var wins1 = 0L | |
var wins2 = 0L | |
var newState : Array<Array<Array<LongArray>>> | |
while (!done) { | |
newState = Array(winningScore + boardSize) { Array(winningScore + boardSize) { Array(boardSize + 1) { LongArray(boardSize + 1) } } } | |
done = true | |
for (score1 in 0 until winningScore) { | |
for (score2 in 0 until winningScore) { | |
for (pos1 in 1..boardSize) { | |
for (pos2 in 1..boardSize) { | |
val stateCount = state[score1][score2][pos1][pos2] | |
if (stateCount == 0L) continue | |
done = false | |
for ((roll, count) in rolls.withIndex()) { | |
val newPos1 = (pos1 - 1 + roll) % boardSize + 1 | |
val newScore1 = score1 + newPos1 | |
if (newScore1 >= 21) wins1 += stateCount * count | |
else newState[newScore1][score2][newPos1][pos2] += stateCount * count | |
} | |
} | |
} | |
} | |
} | |
state = newState | |
if (done) break | |
newState = Array(31) { Array(31) { Array(11) { LongArray(11) } } } | |
for (score1 in 0..20) { | |
for (score2 in 0..20) { | |
for (pos1 in 1..10) { | |
for (pos2 in 1..10) { | |
val stateCount = state[score1][score2][pos1][pos2] | |
if (stateCount == 0L) continue | |
done = false | |
for ((roll, count) in rolls.withIndex()) { | |
val newPos2 = (pos2 - 1 + roll) % boardSize + 1 | |
val newScore2 = score2 + newPos2 | |
if (newScore2 >= 21) wins2 += stateCount * count | |
else newState[score1][newScore2][pos1][newPos2] += stateCount * count | |
} | |
} | |
} | |
} | |
} | |
state = newState | |
} | |
println(wins1.coerceAtLeast(wins2)) | |
} | |
/* | |
Player 1 starting position: 4 | |
Player 2 starting position: 8 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment