Completed both parts of Day 7 puzzle

main
oabrivard 2 years ago
parent 4262c9e715
commit 9a9f6dfb22

@ -0,0 +1,274 @@
package day7
import (
"fmt"
"log"
"sort"
"strconv"
"strings"
)
type Hand struct {
original string
cards []rune
bid int
strength int
}
func EvalHands(lines []string) int {
hands := []Hand{}
/*
1+1+1+1+1 1 1*1*1*1*1
2+1+1+1 3 3*1*1*1
2+2 9 3*3
3+1+1 7 7*1*1
3+2 21 7*3
4+1 11 11*1
5+0 13 13
*/
strengthConv := make([]int, 22)
strengthConv[1] = 1
strengthConv[3] = 2
strengthConv[9] = 3
strengthConv[7] = 4
strengthConv[21] = 5
strengthConv[11] = 6
strengthConv[13] = 7
for _, l := range lines {
strength := 1
counts := make([]int, 13)
parts := strings.Fields(l)
cards := []rune(parts[0])
bid, _ := strconv.Atoi(parts[1])
for i, card := range cards {
switch card {
case '2', '3', '4', '5', '6', '7', '8', '9':
counts[card-'2']++
case 'T':
counts[8]++
cards[i] = 'a'
case 'J':
counts[9]++
cards[i] = 'b'
case 'Q':
counts[10]++
cards[i] = 'c'
case 'K':
counts[11]++
cards[i] = 'd'
case 'A':
counts[12]++
cards[i] = 'e'
default:
log.Fatalf("invalid card: %v", card)
}
}
for _, count := range counts {
switch count {
case 2:
strength *= 3
case 3:
strength *= 7
case 4:
strength *= 11
case 5:
strength *= 13
}
}
h := Hand{
cards: cards,
bid: bid,
strength: strengthConv[strength],
}
hands = append(hands, h)
}
sort.Slice(hands, func(i, j int) bool {
if hands[i].strength == hands[j].strength {
for k := 0; k < 5; k++ {
if hands[i].cards[k] != hands[j].cards[k] {
return hands[i].cards[k] < hands[j].cards[k]
}
}
return false
} else {
return hands[i].strength < hands[j].strength
}
})
result := 0
for i, hand := range hands {
result += (i + 1) * hand.bid
}
return result
}
func EvalHandsWithJoker(lines []string) int {
hands := []Hand{}
/*
1+1+1+1+1 1 1*1*1*1*1
2+1+1+1 3 3*1*1*1
2+2 9 3*3
3+1+1 7 7*1*1
3+2 21 7*3
4+1 11 11*1
5+0 13 13
*/
strengthConv := make([]int, 22)
strengthConv[1] = 1 // high card
strengthConv[3] = 2 // pair
strengthConv[9] = 3 // two pairs
strengthConv[7] = 4 // brelan
strengthConv[21] = 5 // full
strengthConv[11] = 6 // carre
strengthConv[13] = 7 // five
for _, l := range lines {
strength := 1
counts := make([]int, 13)
parts := strings.Fields(l)
original := parts[0]
cards := []rune(parts[0])
bid, _ := strconv.Atoi(parts[1])
countJ := 0
for i, card := range cards {
switch card {
case '2', '3', '4', '5', '6', '7', '8', '9':
counts[card-'2']++
case 'T':
counts[8]++
cards[i] = 'a'
case 'J':
/*
counts[9]++
cards[i] = 'b'
*/
cards[i] = '1' // weakest
countJ++
case 'Q':
counts[10]++
cards[i] = 'c'
case 'K':
counts[11]++
cards[i] = 'd'
case 'A':
counts[12]++
cards[i] = 'e'
default:
log.Fatalf("invalid card: %v", card)
}
}
for _, count := range counts {
/*
if count > 0 && countJ > 0 {
count += countJ
countJ = 0
}
*/
switch count {
case 2:
strength *= 3
case 3:
strength *= 7
case 4:
strength *= 11
case 5:
strength *= 13
}
}
strength = strengthConv[strength]
/*
strengthConv[1] = 1 // high card
strengthConv[3] = 2 // pair
strengthConv[9] = 3 // two pairs
strengthConv[7] = 4 // brelan
strengthConv[21] = 5 // full
strengthConv[11] = 6 // carre
strengthConv[13] = 7 // five
*/
switch strength {
case 1:
if countJ == 4 {
strength = 7
} else if countJ == 3 {
strength = 6
} else if countJ == 2 {
strength = 4
} else if countJ == 1 {
strength = 2
}
case 2:
if countJ == 3 {
strength = 7
} else if countJ == 2 {
strength = 6
} else if countJ == 1 {
strength = 4
}
case 3:
if countJ == 1 {
strength = 5
}
case 4:
if countJ == 2 {
strength = 7
} else if countJ == 1 {
strength = 6
}
case 6:
if countJ == 1 {
strength = 7
}
}
if countJ == 5 {
strength = 7
}
h := Hand{
original: original,
cards: cards,
bid: bid,
strength: strength,
}
hands = append(hands, h)
}
sort.Slice(hands, func(i, j int) bool {
if hands[i].strength == hands[j].strength {
for k := 0; k < 5; k++ {
if hands[i].cards[k] != hands[j].cards[k] {
return hands[i].cards[k] < hands[j].cards[k]
}
}
return false
} else {
return hands[i].strength < hands[j].strength
}
})
result := 0
for i, hand := range hands {
result += (i + 1) * hand.bid
fmt.Println(string(hand.original))
}
return result
}

@ -0,0 +1,57 @@
package day7
import (
"testing"
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
)
func TestEvalHands(t *testing.T) {
lines := []string{
"32T3K 765",
"T55J5 684",
"KK677 28",
"KTJJT 220",
"QQQJA 483",
}
result := EvalHands(lines)
if result != 6440 {
t.Fatalf("expected 6440, got %v", result)
}
}
func TestEvalHandsWithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := EvalHands(lines)
if result != 251029473 {
t.Fatalf("expected 251029473, got %d", result)
}
}
func TestEvalHandsWithJoker(t *testing.T) {
lines := []string{
"32T3K 765",
"T55J5 684",
"KK677 28",
"KTJJT 220",
"QQQJA 483",
}
result := EvalHandsWithJoker(lines)
if result != 5905 {
t.Fatalf("expected 5905, got %v", result)
}
}
func TestEvalHandsWithJokerWithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := EvalHandsWithJoker(lines)
if result != 251003917 {
t.Fatalf("expected 251003917, got %d", result)
}
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save