-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday4_part1.nim
49 lines (47 loc) · 1.93 KB
/
day4_part1.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import std/sequtils
import strutils
type Field = object
value: int
checked: bool
type FieldRef = ref Field
type Board = seq[seq[FieldRef]]
type Winner = tuple[board: Board, winningNumber: int]
func findWinningBoard(boards: seq[Board], selectedNumbers: seq[int]): Winner =
for selectedNumber in selectedNumbers:
for board in boards:
var hasWinningNumber = -1
for line in board:
var allChecked = true
for field in line:
field.checked = field.checked or field.value == selectedNumber
allChecked = allChecked and field.checked
if allChecked: hasWinningNumber = selectedNumber
for columnIdx in 0..board.len - 1:
var allChecked = true
for line in board:
line[columnIdx].checked = line[columnIdx].checked or line[columnIdx].value == selectedNumber
allChecked = allChecked and line[columnIdx].checked
if allChecked: hasWinningNumber = selectedNumber
if hasWinningNumber != -1: return (board, hasWinningNumber)
func parseBoards(lines: seq[string]): seq[Board] =
lines.map(func (line: string): seq[FieldRef] =
line
.splitWhitespace
.map(
func (strN: string): FieldRef = FieldRef(value: parseInt(strN), checked: false)
)
)
.distribute(int(lines.len/5))
func sumUnmarked(board: Board): int = foldl(
board,
foldl(b, a + (if b.checked: 0 else: b.value), a),
0
)
var fileLines = lines("data/input-day4.txt").toSeq
var selectedNumbers = fileLines[0].split(',').map(parseInt)
fileLines.delete(0)
var parsedBoards = fileLines
.filter(func (line: string): bool = not line.isEmptyOrWhitespace)
.parseBoards
let (board, winningNumber) = parsedBoards.findWinningBoard(selectedNumbers)
echo board.sumUnmarked * winningNumber