You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

275 lines
4.7 KiB
Go

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
}