# Copyright 2021 Christian Ulrich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # usage: ./part1 < input import sequtils import strutils type Board = array[5, array[5, int8]] iterator lines(board: Board): array[5, int8] = for i in 0 .. high(Board): yield board[i] iterator columns(board: Board): array[5, int8] = for i in 0 .. high(board[0]): var column: array[5, int8] for j in 0 .. high(Board): column[j] = board[j][i] yield column proc check(board: var Board, val: int8) = for i in 0 .. high(Board): for cellIndex, cell in board[i].pairs(): if cell == val: board[i][cellIndex] = -1 proc readDrawnNumbers(): seq[int8] = result = readLine(stdin).split(',').mapIt(int8(parseUint(it))) proc readBoards(): seq[Board] = var line: string board: Board while true: if not readLine(stdin, line): return for i in 0 .. high(Board): if not readLine(stdin, line): return board[i][0 .. high(Board)] = line.splitWhitespace(4) .mapIt(int8(parseUint(it))) result.add(board) proc bingoScore(board: Board, latestNumber: int8): int = var unmarkedSum = 0 for line in board.lines(): unmarkedSum.inc(line.foldl(if b >= 0: a + int(b) else: a, 0)) result = unmarkedSum * int(latestNumber) proc bingo(): int = let drawnNumbers = readDrawnNumbers() var boards = readBoards() for number in drawnNumbers: for board in boards.mitems(): board.check(number) for line in board.lines(): if line.allIt(it < 0): return board.bingoScore(number) for column in board.columns(): if column.allIt(it < 0): return board.bingoScore(number) raise newException(ValueError, "there is no winner") proc main(): int = try: echo bingo() except Exception as error: echo error.msg result = -1 when isMainModule: quit(main())