Skip to content

Instantly share code, notes, and snippets.

@waynejo
Created May 30, 2021 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save waynejo/56bf25b8e2cf12407081e55c3705db45 to your computer and use it in GitHub Desktop.
Save waynejo/56bf25b8e2cf12407081e55c3705db45 to your computer and use it in GitHub Desktop.
import java.io.FileInputStream
import scala.io.StdIn
case class Round(player1: Vector[Int], player2: Vector[Int])
case class Game(round: Round, history: Set[Round]) {
def player1Win(): Game = {
Game(Round(round.player1.tail :+ round.player1.head :+ round.player2.head, round.player2.tail), history + round)
}
def player2Win(): Game = {
Game(Round(round.player1.tail, round.player2.tail :+ round.player2.head :+ round.player1.head), history + round)
}
}
def score(deck: Vector[Int]): Int = {
deck.zipWithIndex.foldLeft(0) { case (acc, (value, idx)) =>
acc + (deck.length - idx) * value
}
}
def solve22_1(player1: Vector[Int], player2: Vector[Int]): Int = {
if player1.isEmpty then
score(player2)
else if player2.isEmpty then
score(player1)
else if player1.head > player2.head then
solve22_1(player1.tail :+ player1.head :+ player2.head, player2.tail)
else
solve22_1(player1.tail, player2.tail :+ player2.head :+ player1.head)
}
def winnerDeck(games: Vector[Game]): Vector[Int] = {
val game = games.last
val round = game.round
val player1 = round.player1
val player2 = round.player2
if player1.isEmpty then
games.init.lastOption match
case Some(lastGame) =>
winnerDeck(games.init.init :+ lastGame.player2Win())
case _ =>
player2
else if player2.isEmpty || game.history.contains(round) then
games.init.lastOption match
case Some(lastGame) =>
winnerDeck(games.init.init :+ lastGame.player1Win())
case _ =>
player1
else
if player1.head < player1.length && player2.head < player2.length then
winnerDeck(games :+ Game(Round(player1.tail.take(player1.head), player2.tail.take(player2.head)), Set()))
else if player1.head > player2.head then
winnerDeck(games.init :+ game.player1Win())
else
winnerDeck(games.init :+ game.player2Win())
}
def solve22_2(player1: Vector[Int], player2: Vector[Int]): Int = {
val deck = winnerDeck(Vector(Game(Round(player1, player2), Set())))
score(deck)
}
def readCardDeck(): Vector[Int] = {
Iterator.continually(StdIn.readLine())
.takeWhile(line => null != line && line.trim.nonEmpty)
.toVector
.tail
.map(_.toInt)
}
@main def solve22() =
val in = new FileInputStream("example22-1.in")
System.setIn(in)
val player1 = readCardDeck()
val player2 = readCardDeck()
println(solve22_1(player1, player2)) // 33434
println(solve22_2(player1, player2)) // 31657
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment