Skip to content

Commit 70a2772

Browse files
committed
feat(day21): part 2
1 parent 6df8504 commit 70a2772

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

day21-2.sc

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import common.loadPackets
2+
3+
import scala.annotation.tailrec
4+
5+
val input = loadPackets(List("day21.txt")).map(_.split(": ")(1).toInt)
6+
7+
val threeThrows =
8+
(for(x <- Range.inclusive(1, 3);
9+
y <- Range.inclusive(1, 3);
10+
z <- Range.inclusive(1, 3)) yield (x + y + z, 1)).groupMapReduce(_._1)(_._2)(_ + _)
11+
12+
case class State(player1Position: Int = input.head,
13+
player2Position: Int = input(1),
14+
player1Score: Int = 0,
15+
player2Score: Int = 0,
16+
player1Turn: Boolean = true) {
17+
def wrap(v: Int): Int = (v - 1) % 10 + 1
18+
19+
def won: Boolean = player1Score >= 21 | player2Score >= 21
20+
21+
def winner: Option[Int] =
22+
if (player1Score >= 21) Some(1)
23+
else if (player2Score >= 21) Some(2)
24+
else None
25+
26+
def next(): Map[State, Int] = {
27+
if (won) Map(this -> 1)
28+
else threeThrows.map { case (roll, count) =>
29+
if (player1Turn) {
30+
val newPos = wrap(player1Position + roll)
31+
copy(player1Position = newPos,
32+
player1Score = player1Score + newPos,
33+
player1Turn = !player1Turn) -> count
34+
} else {
35+
val newPos = wrap(player2Position + roll)
36+
copy(player2Position = newPos,
37+
player2Score = player2Score + newPos,
38+
player1Turn = !player1Turn) -> count
39+
}
40+
}
41+
}
42+
}
43+
44+
val initial: Map[State, Long] = Map(State(input.head, input(1)) -> 1L)
45+
def nextState(universes: Map[State, Long]): Map[State, Long] =
46+
universes.toList.flatMap {
47+
case (universe: State, count: Long) => universe.next().view.mapValues(_ * count)
48+
}.groupMapReduce(_._1)(_._2)(_ + _)
49+
50+
@tailrec
51+
def part2(universes: Map[State, Long]): Long = {
52+
if (universes.keySet.forall(_.won)) {
53+
val counts: Map[Int, Long] = universes.groupMapReduce(_._1.winner.get)(_._2)(_ + _)
54+
counts.values.max
55+
} else part2(nextState(universes))
56+
}
57+
58+
part2(initial)

0 commit comments

Comments
 (0)