Den 9., ačkoliv se jevil jednoduše, zákeřnost jeho zadání přišla záhy 🙂 . První část jsem ještě zvládl sám, ale v části druhé jsem měl již perfomance problém. Ačkoliv se mi mé první řešení podařilo zrychlit až 25x, stále to bylo velmi málo. A tak jsem musel zvolit zcela jiný přístup, kde jsem se musel inspirovat řešením ostatních na Kotlin Slacku, což nakonec rychle vedlo ke kýženému cíli:
import com.google.common.collect.Iterables import com.svetylkovo.rojo.Rojo import java.io.File data class ElfPlayer(val id: Int, var score: Long = 0) data class Marble(val number: Int) { var next: Marble = this var prev: Marble = this fun remove() { prev.next = next next.prev = prev } fun add(marble: Marble) { next.run { next.prev = marble marble.next = next marble.prev = this next = marble } } } class Game( val players: List<ElfPlayer>, val lastMarbleNumber: Int ) { var current = Marble(0) fun start() { var nextMarbleNumber = 0 Iterables.cycle(players).forEach { player -> if (nextMarbleNumber > lastMarbleNumber) return nextTurn(player, ++nextMarbleNumber) } } fun winner() = players.maxBy { it.score } private fun nextTurn(player: ElfPlayer, nextMarbleNumber: Int) { val nextMarble = Marble(nextMarbleNumber) when { nextMarbleNumber % 23 == 0 -> { player.score += nextMarbleNumber moveBackward(7) val marbleToRemove = current player.score += marbleToRemove.number marbleToRemove.remove() moveForward(1) } else -> { current.add(nextMarble) current = nextMarble } } } private fun moveBackward(n: Int) { repeat(n) { current = current.prev } } private fun moveForward(n: Int) { repeat(n) { current = current.next } } } fun main() { val input = File("input9.txt").readText() val (players, lastMarble) = Rojo.asList("\\d+", input).map { it.toInt() } //A val elfPlayersA = List(players) { ElfPlayer(it + 1) } val gameA = Game(elfPlayersA, lastMarble) gameA.start() println(gameA.winner()) //B val elfPlayersB = List(players) { ElfPlayer(it + 1) } val gameB = Game(elfPlayersB, lastMarble * 100) gameB.start() println(gameB.winner()) }