I ended up with a solution that uses strings only, with regards to the advent
problem:
import std/sequtils
import std/strutils
import std/enumerate
import std/tables
import std/algorithm
var
input: string
hands, lines: seq[string]
handTypes = initTable[string, int]()
bids = initTable[string, int]()
hand: string
bid, score: int
input = readFile("input_7.txt")
input = input.replace("A", "Z").replace("K", "Y").replace("Q",
"X").replace("J", "1").replace("T", "V")
lines = input.split("\n")
proc getScore(hand: string): int =
var counts = newCountTable(hand)
if '1' in counts and len(counts)>1:
var numJs = counts['1']
counts.del('1')
var l = largest(counts) # We removed Js, so it won't be the largest
counts[l.key] = counts[l.key] + numJs
var score = case largest(counts).val:
of 1:
1
of 2:
if len(counts) == 3: 3 else: 2
of 3:
if len(counts) == 2: 5 else: 4
of 4:
6
of 5:
7
else:
0
assert score != 0
return score
for line in lines:
let info = line.split(" ")
var (hand, bid) = (info[0], info[1].parseInt())
let score = getScore(hand)
hand = $score & hand # This enables us to sort by score
hands.add(hand)
bids[hand] = bid # All hands are unique
assert len(hands) == len(bids) # assert all hands are indeed unique
var result: int = 0
sort(hands)
for i, hand in enumerate(hands):
result += (i+1) * bids[hand]
echo result
Run
But on a more general basis I'm not satisfied with a parser, as they suggest in
the DNA question, because what guarantees do you have that some guy doesn't
just bypass it and hands you an unvalidated variable if the constraints aren't
encoded in the type.
Like in this snippet:
import std/strutils
import std/sets
import std/setutils
type Hand = distinct string
proc validateHand(input: string): Hand =
assert len(input) == 5, "Wrong hand size: " & input & " is " &
$len(input) & " chars."
var forbiddenChars: set[char] = input.toSet() - {'A', 'K', 'Q', 'J', 'T',
'9', '8', '7', '6', '5', '4', '3', '2'}
assert len(forbiddenChars) == 0, "Hand includes forbidden cards: " &
$forbiddenChars
return Hand(input)
var a: Hand = validateHand("AKT33")
var b: Hand = Hand("ABCDEFGHIJKL")
echo cast[string](a)
echo cast[string](b)
Run