Watch
1
0
Fork
You've already forked advent-of-code
0
advent-of-code/2023/day04.nim
2023-12-03 21:37:58 -08:00

67 lines
1.4 KiB
Nim

import std/enumerate
import std/math
import std/sequtils
import std/sets
import std/strscans
import std/strutils
import std/tables
type Card = tuple
id: int
winning: HashSet[int]
mine: HashSet[int]
proc parseCard(line: string): Card =
var winning, mine: string
if not scanf(line, "Card$s$i: $* | $*$.", result.id, winning, mine):
raise newException(ValueError, line)
for num in winning.strip.splitWhitespace:
result.winning.incl num.parseInt
for num in mine.strip.splitWhitespace:
result.mine.incl num.parseInt
proc parseCards(text: string): seq[Card] =
let lines = text.strip.splitLines()
for line in lines:
result.add parseCard(line)
func matches(card: Card): int =
len(card.winning * card.mine)
func score(card: Card): int =
let matches = card.matches
if matches > 0:
2 ^ (matches - 1)
else:
0
proc part1(): int =
let text = readFile("input/day04.txt")
let cards = parseCards(text)
for card in cards:
result.inc card.score
proc part2(): int =
let text = readFile("input/day04.txt")
let cards = parseCards(text)
var multiples: CountTable[int]
for card in cards:
multiples.inc card.id
let extras = card.matches
let scale = multiples[card.id]
for id in (card.id + 1) .. (card.id + extras):
multiples.inc(id, scale)
for (id, count) in multiples.pairs:
result += count
echo part1()
echo part2()