This commit is contained in:
Paul-Henri Froidmont 2021-12-09 02:41:22 +01:00
parent 1747cd8c93
commit 0f233d908d
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
2 changed files with 675 additions and 0 deletions

74
aoc/src/Day4.scala Normal file
View file

@ -0,0 +1,74 @@
import scala.io.Source
object Day4 extends App:
val input = Source
.fromURL(getClass.getResource("day4Input.txt"))
.mkString
final case class Bingo(boards: Array[Board], playedNumbers: Seq[Int]):
def playNumber(number: Int) =
Bingo(
boards.map(board => if (board.isWinner) board else board.mark(number)),
playedNumbers.appended(number)
)
def winningBoards: Seq[Board] = boards
.filter(_.isWinner)
.map(board => (board, board.lastMarked.map(playedNumbers.indexOf(_))))
.sortBy(_._2)
.map(_._1)
val gameOver = boards.forall(_.isWinner)
object Bingo:
def parse(input: Array[String]): Bingo =
Bingo(input.map(Board.parse), Seq())
final case class Board(
val rows: Array[Array[Cell]],
lastMarked: Option[Int] = None
):
val isWinner: Boolean = rows.exists(_.forall(_.marked)) ||
rows.transpose.exists(_.forall(_.marked))
def mark(number: Int): Board =
Board(
rows.map(_.map(_.mark(number))),
Some(number)
)
def score: Int =
rows.flatMap(_.filterNot(_.marked).map(_.value)).sum *
lastMarked.getOrElse(0)
object Board:
def parse(input: String) =
Board(
input
.split('\n')
.map(
_.split(' ')
.filter(_.nonEmpty)
.map(Cell.parse)
)
)
final case class Cell(value: Int, marked: Boolean = false):
def mark(number: Int): Cell =
if (number == value) Cell(value, true) else this
object Cell:
def parse(input: String) = Cell(input.toInt)
val numbersAndBoardsInput = input.split("\n\n")
val drawnNumbers = numbersAndBoardsInput.head.split(',').map(_.toInt)
val initialState = Bingo.parse(numbersAndBoardsInput.tail)
val finalState = drawnNumbers.foldLeft(initialState)(_.playNumber(_))
val firstWinningBoard = finalState.winningBoards.head
println(s"Part 1: ${firstWinningBoard.score}")
val lastWinningBoard = finalState.winningBoards.last
println(s"Part 2: ${lastWinningBoard.score}")