diff options
Diffstat (limited to 'src/Day04.kt')
-rw-r--r-- | src/Day04.kt | 124 |
1 files changed, 63 insertions, 61 deletions
diff --git a/src/Day04.kt b/src/Day04.kt index 4f93a67..96cdf3b 100644 --- a/src/Day04.kt +++ b/src/Day04.kt @@ -1,95 +1,97 @@ -class Bingo(private val revealQueue: ArrayDeque<Int>, private val boards: List<Board>) { - companion object { - fun fromString(input: String): Bingo { - val sections = input.trim().split("(\\r?\\n){2}".toRegex()) +object Day04 { + private class Bingo(private val revealQueue: ArrayDeque<Int>, private val boards: List<Board>) { + companion object { + fun fromString(input: String): Bingo { + val sections = input.trim().split("(\\r?\\n){2}".toRegex()) - val revealQueueString = sections.first() - val revealQueue = ArrayDeque(revealQueueString.split(",").map(String::toInt)) + val revealQueueString = sections.first() + val revealQueue = ArrayDeque(revealQueueString.split(",").map(String::toInt)) - val boards = sections.drop(1).map { Board.fromMatrixString(it) } + val boards = sections.drop(1).map { Board.fromMatrixString(it) } - return Bingo(revealQueue, boards) + return Bingo(revealQueue, boards) + } } - } - fun getResults() = sequence { - while (revealQueue.isNotEmpty() && boards.any { !it.didWin }) { - val number = revealQueue.removeFirst() + fun getResults() = sequence { + while (revealQueue.isNotEmpty() && boards.any { !it.didWin }) { + val number = revealQueue.removeFirst() - for (board in boards.filter { !it.didWin }) { - board.reveal(number) + for (board in boards.filter { !it.didWin }) { + board.reveal(number) - if (board.didWin) { - yield(board.sumOfUnmarked * number) + if (board.didWin) { + yield(board.sumOfUnmarked * number) + } } } } - } - class Board(private var rows: List<List<Square>>) { - companion object { - fun fromMatrixString(matrixString: String): Board = Board( - matrixString.trim().split("\\r?\\n".toRegex()).map { rowString -> - rowString.trim().split("\\s+".toRegex()).map { squareString -> - Square.Unmarked(squareString.toInt()) + private class Board(private var rows: List<List<Square>>) { + companion object { + fun fromMatrixString(matrixString: String): Board = Board( + matrixString.trim().split("\\r?\\n".toRegex()).map { rowString -> + rowString.trim().split("\\s+".toRegex()).map { squareString -> + Square.Unmarked(squareString.toInt()) + } } - } - ) + ) - private const val SIZE = 5 + private const val SIZE = 5 - private val ROWS = (0 until SIZE).map { row -> - (0 until SIZE).map { square -> - Pair(row, square) + private val ROWS = (0 until SIZE).map { row -> + (0 until SIZE).map { square -> + Pair(row, square) + } } - } - private val COLUMNS = (0 until SIZE).map { column -> - (0 until SIZE).map { square -> - Pair(square, column) + private val COLUMNS = (0 until SIZE).map { column -> + (0 until SIZE).map { square -> + Pair(square, column) + } } - } - private val WINNING_CONFIGURATIONS = ROWS + COLUMNS - } + private val WINNING_CONFIGURATIONS = ROWS + COLUMNS + } - fun reveal(number: Int) { - rows = rows.map { row -> - row.map { square -> - if (square is Square.Unmarked && square.number == number) Square.Marked else square + fun reveal(number: Int) { + rows = rows.map { row -> + row.map { square -> + if (square is Square.Unmarked && square.number == number) Square.Marked else square + } } } - } - val didWin: Boolean - get() = WINNING_CONFIGURATIONS.any { configuration -> - configuration.all { (row, column) -> rows[row][column] is Square.Marked } - } + val didWin: Boolean + get() = WINNING_CONFIGURATIONS.any { configuration -> + configuration.all { (row, column) -> rows[row][column] is Square.Marked } + } - val sumOfUnmarked: Int - get() = rows.fold(0) { racc, row -> - racc + row.fold(0) { sacc, square -> - sacc + if (square is Square.Unmarked) square.number else 0 + val sumOfUnmarked: Int + get() = rows.fold(0) { rowAcc, row -> + rowAcc + row.fold(0) { squareAcc, square -> + squareAcc + if (square is Square.Unmarked) square.number else 0 + } } - } - sealed class Square { - object Marked : Square() - class Unmarked(val number: Int) : Square() + sealed class Square { + object Marked : Square() + class Unmarked(val number: Int) : Square() + } } } + + fun bothParts(input: String) = Bingo.fromString(input).getResults().let { it.first() to it.last() } } fun main() { - fun part1(input: String): Int = Bingo.fromString(input).getResults().first() - - fun part2(input: String): Int = Bingo.fromString(input).getResults().last() - val testInput = readInputAsString("Day04_test") - check(part1(testInput) == 4512) - check(part2(testInput) == 1924) + val testOutput = Day04.bothParts(testInput) + check(testOutput.first == 4512) + check(testOutput.second == 1924) val input = readInputAsString("Day04") - println(part1(input)) - println(part2(input)) + val output = Day04.bothParts(input) + println(output.first) + println(output.second) } |