From 1565026e68dcb365a4b6b005d371351b206b1869 Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Sat, 4 Dec 2021 15:42:45 +0100 Subject: [PATCH] improve memory footprint by encoding checked cells as negative number --- day04/part1.nim | 29 ++++++++++++++--------------- day04/part2.nim | 29 ++++++++++++++--------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/day04/part1.nim b/day04/part1.nim index 3d95708..cf8c4a6 100644 --- a/day04/part1.nim +++ b/day04/part1.nim @@ -19,28 +19,27 @@ import sequtils import strutils type - Cell = tuple[val: uint8, checked: bool] - Board = array[5, array[5, Cell]] + Board = array[5, array[5, int8]] -iterator lines(board: Board): array[5, Cell] = +iterator lines(board: Board): array[5, int8] = for i in 0 .. high(Board): yield board[i] -iterator columns(board: Board): array[5, Cell] = +iterator columns(board: Board): array[5, int8] = for i in 0 .. high(board[0]): - var column: array[5, Cell] + var column: array[5, int8] for j in 0 .. high(Board): column[j] = board[j][i] yield column -proc check(board: var Board, val: uint8) = +proc check(board: var Board, val: int8) = for i in 0 .. high(Board): for cellIndex, cell in board[i].pairs(): - if cell.val == val: - board[i][cellIndex].checked = true + if cell == val: + board[i][cellIndex] = -1 -proc readDrawnNumbers(): seq[uint8] = - result = readLine(stdin).split(',').mapIt(uint8(parseUint(it))) +proc readDrawnNumbers(): seq[int8] = + result = readLine(stdin).split(',').mapIt(int8(parseUint(it))) proc readBoards(): seq[Board] = var @@ -53,13 +52,13 @@ proc readBoards(): seq[Board] = if not readLine(stdin, line): return board[i][0 .. high(Board)] = line.splitWhitespace(4) - .mapIt((uint8(parseUint(it)), false)) + .mapIt(int8(parseUint(it))) result.add(board) -proc bingoScore(board: Board, latestNumber: uint8): int = +proc bingoScore(board: Board, latestNumber: int8): int = var unmarkedSum = 0 for line in board.lines(): - unmarkedSum.inc(line.foldl(if not b.checked: a + int(b.val) else: a, 0)) + unmarkedSum.inc(line.foldl(if b >= 0: a + int(b) else: a, 0)) result = unmarkedSum * int(latestNumber) proc bingo(): int = @@ -69,10 +68,10 @@ proc bingo(): int = for board in boards.mitems(): board.check(number) for line in board.lines(): - if line.allIt(it.checked): + if line.allIt(it < 0): return board.bingoScore(number) for column in board.columns(): - if column.allIt(it.checked): + if column.allIt(it < 0): return board.bingoScore(number) raise newException(ValueError, "there is no winner") diff --git a/day04/part2.nim b/day04/part2.nim index f7dcfd3..94e9ce4 100644 --- a/day04/part2.nim +++ b/day04/part2.nim @@ -19,28 +19,27 @@ import sequtils import strutils type - Cell = tuple[val: uint8, checked: bool] - Board = array[5, array[5, Cell]] + Board = array[5, array[5, int8]] -iterator lines(board: Board): array[5, Cell] = +iterator lines(board: Board): array[5, int8] = for i in 0 .. high(Board): yield board[i] -iterator columns(board: Board): array[5, Cell] = +iterator columns(board: Board): array[5, int8] = for i in 0 .. high(board[0]): - var column: array[5, Cell] + var column: array[5, int8] for j in 0 .. high(Board): column[j] = board[j][i] yield column -proc check(board: var Board, val: uint8) = +proc check(board: var Board, val: int8) = for i in 0 .. high(Board): for cellIndex, cell in board[i].pairs(): - if cell.val == val: - board[i][cellIndex].checked = true + if cell == val: + board[i][cellIndex] = -1 -proc readDrawnNumbers(): seq[uint8] = - result = readLine(stdin).split(',').mapIt(uint8(parseUint(it))) +proc readDrawnNumbers(): seq[int8] = + result = readLine(stdin).split(',').mapIt(int8(parseUint(it))) proc readBoards(): seq[Board] = var @@ -53,13 +52,13 @@ proc readBoards(): seq[Board] = if not readLine(stdin, line): return board[i][0 .. high(Board)] = line.splitWhitespace(4) - .mapIt((uint8(parseUint(it)), false)) + .mapIt(int8(parseUint(it))) result.add(board) -proc bingoScore(board: Board, latestNumber: uint8): int = +proc bingoScore(board: Board, latestNumber: int8): int = var unmarkedSum = 0 for line in board.lines(): - unmarkedSum.inc(line.foldl(if not b.checked: a + int(b.val) else: a, 0)) + unmarkedSum.inc(line.foldl(if b >= 0: a + int(b) else: a, 0)) result = unmarkedSum * int(latestNumber) proc bingo(): int = @@ -69,10 +68,10 @@ proc bingo(): int = for boardIndex, board in boards.mpairs(): board.data.check(number) for line in board.data.lines(): - if line.allIt(it.checked): + if line.allIt(it < 0): board.finished = true for column in board.data.columns(): - if column.allIt(it.checked): + if column.allIt(it < 0): board.finished = true if boards.len() == 1 and boards[0].finished: return boards[0].data.bingoScore(number)