2023 Day 7 Part 2
This commit is contained in:
parent
9f494e7341
commit
8c18dcda69
1 changed files with 103 additions and 7 deletions
110
2023/day07.nim
110
2023/day07.nim
|
|
@ -36,6 +36,14 @@ func parseHand(text: string): Hand =
|
||||||
func parseHands(text: string): seq[Hand] =
|
func parseHands(text: string): seq[Hand] =
|
||||||
text.strip.splitLines.map(parseHand)
|
text.strip.splitLines.map(parseHand)
|
||||||
|
|
||||||
|
const five = 7
|
||||||
|
const four = 6
|
||||||
|
const full = 5
|
||||||
|
const three = 4
|
||||||
|
const twoPair = 3
|
||||||
|
const pair = 2
|
||||||
|
const high = 1
|
||||||
|
|
||||||
func strength(hand: Hand): int =
|
func strength(hand: Hand): int =
|
||||||
let count = newCountTable(hand.cards)
|
let count = newCountTable(hand.cards)
|
||||||
|
|
||||||
|
|
@ -44,19 +52,19 @@ func strength(hand: Hand): int =
|
||||||
counts.inc v
|
counts.inc v
|
||||||
|
|
||||||
if counts[5] > 0:
|
if counts[5] > 0:
|
||||||
return 7
|
return five
|
||||||
if counts[4] > 0:
|
if counts[4] > 0:
|
||||||
return 6
|
return four
|
||||||
if counts[3] > 0:
|
if counts[3] > 0:
|
||||||
if counts[2] > 0:
|
if counts[2] > 0:
|
||||||
return 5
|
return full
|
||||||
else:
|
else:
|
||||||
return 4
|
return three
|
||||||
if counts[2] == 2:
|
if counts[2] == 2:
|
||||||
return 3
|
return twoPair
|
||||||
if counts[2] == 1:
|
if counts[2] == 1:
|
||||||
return 2
|
return pair
|
||||||
return 1
|
return high
|
||||||
|
|
||||||
func cmpHand(a: Hand, b: Hand): int =
|
func cmpHand(a: Hand, b: Hand): int =
|
||||||
let strength = cmp(a.strength, b.strength)
|
let strength = cmp(a.strength, b.strength)
|
||||||
|
|
@ -79,4 +87,92 @@ proc part1(): int =
|
||||||
for (rank, hand) in enumerate(hands):
|
for (rank, hand) in enumerate(hands):
|
||||||
result += (rank + 1) * hand.bid
|
result += (rank + 1) * hand.bid
|
||||||
|
|
||||||
|
func strengthJoker(hand: Hand): int =
|
||||||
|
let count = newCountTable(hand.cards)
|
||||||
|
|
||||||
|
let jokers = count[1]
|
||||||
|
|
||||||
|
var regular: CountTable[int]
|
||||||
|
for card, count in pairs(count):
|
||||||
|
if card == 1:
|
||||||
|
continue
|
||||||
|
regular.inc count
|
||||||
|
|
||||||
|
if regular[5] > 0:
|
||||||
|
return five
|
||||||
|
if regular[4] > 0:
|
||||||
|
if jokers == 1:
|
||||||
|
return five
|
||||||
|
return four
|
||||||
|
if regular[3] > 0:
|
||||||
|
case jokers:
|
||||||
|
of 2: return five
|
||||||
|
of 1: return four
|
||||||
|
else: discard
|
||||||
|
if regular[2] > 0:
|
||||||
|
return full
|
||||||
|
return three
|
||||||
|
if regular[2] == 2:
|
||||||
|
if jokers == 1:
|
||||||
|
return full
|
||||||
|
return twoPair
|
||||||
|
if regular[2] == 1:
|
||||||
|
case jokers:
|
||||||
|
of 3: return five
|
||||||
|
of 2: return four
|
||||||
|
of 1: return three
|
||||||
|
else: return pair
|
||||||
|
|
||||||
|
case jokers:
|
||||||
|
of 5: return five
|
||||||
|
of 4: return five
|
||||||
|
of 3: return four
|
||||||
|
of 2: return three
|
||||||
|
of 1: return pair
|
||||||
|
else: return high
|
||||||
|
|
||||||
|
func cmpHandJoker(a: Hand, b: Hand): int =
|
||||||
|
let strength = cmp(a.strengthJoker, b.strengthJoker)
|
||||||
|
if strength != 0:
|
||||||
|
return strength
|
||||||
|
|
||||||
|
for (aa, bb) in zip(a.cards, b.cards):
|
||||||
|
let card = cmp(aa, bb)
|
||||||
|
if card != 0:
|
||||||
|
return card
|
||||||
|
|
||||||
|
func parseCardJoker(c: char): int =
|
||||||
|
case c:
|
||||||
|
of 'A': 14
|
||||||
|
of 'K': 13
|
||||||
|
of 'Q': 12
|
||||||
|
of 'J': 1
|
||||||
|
of 'T': 10
|
||||||
|
of '9': 9
|
||||||
|
of '8': 8
|
||||||
|
of '7': 7
|
||||||
|
of '6': 6
|
||||||
|
of '5': 5
|
||||||
|
of '4': 4
|
||||||
|
of '3': 3
|
||||||
|
of '2': 2
|
||||||
|
else: 0
|
||||||
|
|
||||||
|
func parseHandJoker(text: string): Hand =
|
||||||
|
let parts = text.strip.splitWhitespace
|
||||||
|
(parts[0].map(parseCardJoker), parts[1].parseInt)
|
||||||
|
|
||||||
|
func parseHandsJoker(text: string): seq[Hand] =
|
||||||
|
text.strip.splitLines.map(parseHandJoker)
|
||||||
|
|
||||||
|
proc part2(): int =
|
||||||
|
let text = readFile("input/day07.txt")
|
||||||
|
var hands = parseHandsJoker(text)
|
||||||
|
|
||||||
|
hands.sort(cmpHandJoker)
|
||||||
|
|
||||||
|
for (rank, hand) in enumerate(hands):
|
||||||
|
result += (rank + 1) * hand.bid
|
||||||
|
|
||||||
echo part1()
|
echo part1()
|
||||||
|
echo part2()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue