Watch
1
0
Fork
You've already forked advent-of-code
0

2023 Day 7 Part 2

This commit is contained in:
Jeremy Kaplan 2023-12-06 21:47:35 -08:00
commit 8c18dcda69

View file

@ -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()