use scanf+tuples+arrays for day 2

This commit is contained in:
Daylin Morgan 2023-12-02 12:06:32 -06:00
parent a82a0fd125
commit c977c6436f
Signed by: daylin
GPG key ID: C1E52E7DD81DF79F

View file

@ -1,65 +1,55 @@
import std/[strutils, sugar] import std/[strutils, strscans]
const example* = slurp("example.txt").strip() const example* = slurp("example.txt").strip()
const input* = slurp("input.txt").strip() const input* = slurp("input.txt").strip()
type type
Turn = object Color {.pure.} = enum
cubes: seq[(int, string)] red, blue, green
Cubes = array[Color, int]
Game = object Game = object
turns: seq[Turn] turns: seq[Cubes]
proc parseInput(input: string): seq[Game] = proc parseInput(input: string): seq[Game] =
for line in input.splitLines: for line in input.splitLines:
result.add Game() result.add Game()
let turns = line.split(":")[1] let turns = line.split(":")[1]
for turn in turns.split(";"): for turn in turns.split(";"):
result[^1].turns.add Turn() var cubes: Cubes
for cube in turn.split(","): for cubeStr in turn.split(","):
let s = cube.strip().split() var cnt: int
result[^1].turns[^1].cubes.add (parseInt(s[0]),s[1]) var color: string
discard cubeStr.strip().scanf("$i $w", cnt, color)
cubes[parseEnum[Color](color)] = cnt
result[^1].turns.add cubes
proc isValid(turn: Turn): bool = proc isValid(game: Game): bool =
const limits = (red: 12, green: 13, blue: 14) const limits: Cubes = [red: 12, blue: 14, green: 13]
for cube in turn.cubes: for turn in game.turns:
case cube[1]: for col, cnt in turn:
of "red": if cnt > limits[col]:
if cube[0] > limits.red: return false return false
of "green":
if cube[0] > limits.green: return false
of "blue":
if cube[0] > limits.blue: return false
else: discard
return true return true
proc partOne*(input: string): int = proc partOne*(input: string): int =
var games = parseInput(input) var games = parseInput(input)
for i, game in games: for i, game in games:
if collect( if game.isValid():
for turn in game.turns:
if not turn.isValid: turn).len == 0:
result += (i+1) result += (i+1)
proc partTwo*(input: string): int = proc partTwo*(input: string): int =
var games = parseInput(input) var games = parseInput(input)
for i, game in games: for i, game in games:
var mins = (red: 0, green: 0, blue: 0) var mins: Cubes
for turn in game.turns: for turn in game.turns:
for cube in turn.cubes: for col, cnt in turn:
case cube[1]: mins[col] = max(mins[col], cnt)
of "red": mins.red = max(mins.red, cube[0]) result += mins[red] * mins[green] * mins[blue]
of "green": mins.green = max(mins.green, cube[0])
of "blue": mins.blue = max(mins.blue, cube[0])
else: discard
result += mins.red * mins.green * mins.blue
when isMainModule: when isMainModule:
import std/unittest import std/unittest
suite "day 2": suite "day 2":
test "part one": test "part one":
check partOne(example) == 8 check partOne(example) == 8
@ -67,4 +57,3 @@ when isMainModule:
test "part two": test "part two":
check partTwo(example) == 2286 check partTwo(example) == 2286
check partTwo(input) == 83435 check partTwo(input) == 83435