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

Reply via email to