diff --git a/day_04/solution_04b.nim b/day_04/solution_04b.nim new file mode 100644 index 0000000..e41922f --- /dev/null +++ b/day_04/solution_04b.nim @@ -0,0 +1,51 @@ +import std/[cmdline, sequtils, setutils, strformat, strscans, strutils] + +var result = 0 +var fn = if paramCount() > 0: paramStr(1) else: "input_04.txt" +var lines = readFile(fn).strip.splitLines + +# ASSUMPTION: lottery numbers are < 128 +type + Card = ref object + idx: int + play, pot: set[int8] +var cards: seq[Card] + +proc value(card: Card): int = + (card.play * card.pot).len + +#proc `$`(card: Card): string = +# return &"Card idx={card.idx}: value={card.value}" + + +for i, line in lines: + var cardno: int + let cardspec = line.split(":", 1) + + if scanf(cardspec[0].strip, "Card$s$i", cardno): + let card = new Card + card.idx = i + card.play = cardspec[1].split("|")[0].strip.splitWhitespace().mapIt(it.strip).mapIt(it.parseInt).mapIt(it.int8).toSet + card.pot = cardspec[1].split("|")[1].strip.splitWhitespace().mapIt(it.strip).mapIt(it.parseInt).mapIt(it.int8).toSet + #echo &"Card {card.idx}: {card.play}, {card.pot} => {card.value}" + cards.add(card) + +var stack = cards +while stack.len > 0: + result += len(stack) + var extra_cards: seq[Card] + + for card in stack: + if card.value > 0: + extra_cards.add(cards[card.idx + 1..min(card.idx + card.value, cards.len - 1)]) + + stack = extra_cards + +#echo &"Cards processed: {cards.len}" +echo &"Result: {result}" + +case fn: + of "input_04.txt": + assert result == 11787590 + of "sample_input_04.txt": + assert result == 30