day07
This commit is contained in:
parent
926fc844ae
commit
fa73b26e7b
1 changed files with 79 additions and 0 deletions
79
2023/day07.nim
Normal file
79
2023/day07.nim
Normal file
|
@ -0,0 +1,79 @@
|
|||
import std/[algorithm, enumerate, sequtils, sets, strutils, tables]
|
||||
|
||||
type
|
||||
HandType = enum
|
||||
highCard, onePair, twoPair, threeOfAKind,
|
||||
fullHouse, fourOfAKind, fiveOfAKind
|
||||
Hand = tuple[cards: string, typ: HandType, bid: int]
|
||||
|
||||
const
|
||||
handValues = {
|
||||
(5, 0): fiveOfAKind,
|
||||
(4, 1): fourOfAKind,
|
||||
(3, 2): fullHouse,
|
||||
(3, 1): threeOfAKind,
|
||||
(2, 2): twoPair,
|
||||
(2, 1): onePair,
|
||||
(1, 1): highCard,
|
||||
(1, 0): highCard
|
||||
}.toTable
|
||||
|
||||
var cardOrder: string
|
||||
|
||||
proc cmp(x, y: Hand): int =
|
||||
if x.typ != y.typ:
|
||||
return ord(x.typ) - ord(y.typ)
|
||||
for (xc, yc) in zip(x.cards, y.cards):
|
||||
if xc != yc:
|
||||
return cardOrder.find(xc) - cardOrder.find(yc)
|
||||
return 0
|
||||
|
||||
func count(cards: string): seq[int] =
|
||||
let cardTypes = cards.toHashSet()
|
||||
result.add(0)
|
||||
for t in cardTypes:
|
||||
result.add(cards.count(t))
|
||||
result.sort(SortOrder.Descending)
|
||||
|
||||
func handType(cards: string): HandType =
|
||||
let counts = cards.count()
|
||||
result = handValues[(counts[0], counts[1])]
|
||||
|
||||
func handTypeP2(cards: string): HandType =
|
||||
let
|
||||
counts = cards.replace("J", "").count()
|
||||
jokers = cards.count('J')
|
||||
if counts.len > 1:
|
||||
result = handValues[(counts[0] + jokers, counts[1])]
|
||||
else:
|
||||
result = handValues[(counts[0] + jokers, 0)]
|
||||
|
||||
proc hand(line: string, handType: proc(c: string): HandType): Hand =
|
||||
let
|
||||
sp = line.split(' ')
|
||||
(cards, bid) = (sp[0], sp[1].parseInt)
|
||||
typ = cards.handType()
|
||||
result = (cards, typ, bid)
|
||||
|
||||
proc winnings(hands: seq[Hand]): int =
|
||||
for (rank, hand) in enumerate(1, hands):
|
||||
result += hand.bid * rank
|
||||
|
||||
proc parse(input: string): seq[Hand] =
|
||||
input.splitLines().mapIt(hand(it, handType))
|
||||
|
||||
proc parseP2(input: string): seq[Hand] =
|
||||
input.splitLines().mapIt(hand(it, handTypeP2))
|
||||
|
||||
proc p1(input: string) =
|
||||
cardOrder = "23456789TJQKA"
|
||||
echo input.parse().sorted(cmp).winnings()
|
||||
|
||||
proc p2(input: string) =
|
||||
cardOrder = "J123456789TQKA"
|
||||
echo input.parseP2().sorted(cmp).winnings()
|
||||
|
||||
when isMainModule:
|
||||
let input = stdin.readAll().strip()
|
||||
p1(input)
|
||||
p2(input)
|
Loading…
Add table
Reference in a new issue