improve memory footprint by encoding checked cells as negative number

This commit is contained in:
Christian Ulrich 2021-12-04 15:42:45 +01:00
parent 25ee296a57
commit 1565026e68
No known key found for this signature in database
GPG Key ID: 8241BE099775A097
2 changed files with 28 additions and 30 deletions

View File

@ -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")

View File

@ -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)