adventofcode/2023/day02.nim
2023-12-06 13:16:37 +01:00

86 lines
1.9 KiB
Nim

import std/[math, sequtils, strutils, sugar]
type
Rules = object
red: int
green: int
blue: int
CubeSet = object
red: int
green: int
blue: int
Game = object
id: int
sets: seq[CubeSet]
const rules = Rules(red: 12, green: 13, blue: 14)
func isPossible(rules: Rules, cubes: CubeSet): bool =
if cubes.red > rules.red:
return false
if cubes.green > rules.green:
return false
if cubes.blue > rules.blue:
return false
return true
func parseGame(game: string): Game =
let
sp = game.split({':', ';'})
sets = sp[1..^1]
result.id = sp[0].split(' ')[1].parseInt()
for set in sets:
var cubes = CubeSet()
for reveal in set.split(','):
let
sp = reveal.strip().split(' ')
let
amount = sp[0].strip().parseInt()
colour = sp[1]
case colour
of "red":
cubes.red = amount
of "green":
cubes.green = amount
of "blue":
cubes.blue = amount
result.sets.add(cubes)
func fewestCubes(sets: seq[CubeSet]): CubeSet =
for cubes in sets:
if cubes.red > result.red:
result.red = cubes.red
if cubes.green > result.green:
result.green = cubes.green
if cubes.blue > result.blue:
result.blue = cubes.blue
proc p1(input: string) =
let
input = input.strip().splitLines()
games = input.map(parseGame)
possibleIds =
collect:
for game in games:
block gameBlock:
for set in game.sets:
if not rules.isPossible(set):
break gameBlock
game.id
echo possibleIds.sum()
proc p2(input: string) =
let
input = input.strip().splitLines()
games = input.map(parseGame).mapIt(it.sets)
fewest = games.map(fewestCubes)
echo fewest.mapIt(it.red * it.green * it.blue).sum()
when isMainModule:
let input = stdin.readAll()
p1(input)
p2(input)