day07
This commit is contained in:
291
2023/go/day07/day07.go
Normal file
291
2023/go/day07/day07.go
Normal file
@@ -0,0 +1,291 @@
|
||||
package day07
|
||||
|
||||
import (
|
||||
_ "fmt"
|
||||
"strings"
|
||||
"sort"
|
||||
"adventofcode2023/utils"
|
||||
|
||||
)
|
||||
type Card int
|
||||
|
||||
const (
|
||||
_ Card = 1 + iota
|
||||
Two
|
||||
Three
|
||||
Four
|
||||
Five
|
||||
Six
|
||||
Seven
|
||||
Eight
|
||||
Nine
|
||||
Ten
|
||||
Jack
|
||||
Queen
|
||||
King
|
||||
Ace
|
||||
)
|
||||
|
||||
type Card2 int
|
||||
const (
|
||||
_ Card2 = iota
|
||||
Joker
|
||||
Two2
|
||||
Three2
|
||||
Four2
|
||||
Five2
|
||||
Six2
|
||||
Seven2
|
||||
Eight2
|
||||
Nine2
|
||||
Ten2
|
||||
Queen2
|
||||
King2
|
||||
Ace2
|
||||
)
|
||||
|
||||
type HandType int
|
||||
|
||||
const (
|
||||
_ HandType = iota
|
||||
HighCard
|
||||
OnePair
|
||||
TwoPair
|
||||
ThreeKind
|
||||
FullHouse
|
||||
FourKind
|
||||
FiveKind
|
||||
)
|
||||
|
||||
type Hand struct {
|
||||
cards [5]Card
|
||||
bid int
|
||||
rank int
|
||||
handType HandType
|
||||
}
|
||||
|
||||
type Hand2 struct {
|
||||
cards [5]Card2
|
||||
bid int
|
||||
rank int
|
||||
handType HandType
|
||||
}
|
||||
|
||||
func Part1(input string) int {
|
||||
total := 0
|
||||
hands := parseInput(1, input)
|
||||
sort.Slice(hands, func(i, j int) bool {
|
||||
if hands[i].handType == hands[j].handType {
|
||||
for k:=0;k<5;k++{
|
||||
if hands[i].cards[k] == hands[j].cards[k] {
|
||||
continue
|
||||
}
|
||||
return hands[i].cards[k] < hands[j].cards[k]
|
||||
}
|
||||
}
|
||||
return hands[i].handType < hands[j].handType
|
||||
})
|
||||
for i,hand := range hands {
|
||||
total += (i+1) * hand.bid
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
func Part2(input string) int {
|
||||
total := 0
|
||||
hands := parseInput(2, input)
|
||||
sort.Slice(hands, func(i, j int) bool {
|
||||
if hands[i].handType == hands[j].handType {
|
||||
for k:=0;k<5;k++{
|
||||
if hands[i].cards[k] == hands[j].cards[k] {
|
||||
continue
|
||||
}
|
||||
if hands[i].cards[k] == Jack {return true}
|
||||
if hands[j].cards[k] == Jack {return false}
|
||||
return hands[i].cards[k] < hands[j].cards[k]
|
||||
}
|
||||
}
|
||||
return hands[i].handType < hands[j].handType
|
||||
})
|
||||
for i,hand := range hands {
|
||||
total += (i+1) * hand.bid
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
func parseInput(part int, input string) ([]Hand) {
|
||||
var hand Hand
|
||||
var hands []Hand
|
||||
lines := strings.Split(input, "\n")
|
||||
for _, line := range lines {
|
||||
tokens := strings.Fields(line)
|
||||
hand.bid = utils.MustAtoi(tokens[1])
|
||||
for i, j := range tokens[0] {
|
||||
hand.cards[i] = toCard(j)
|
||||
}
|
||||
hand.handType = toHandType(part, hand.cards)
|
||||
hands = append(hands, hand)
|
||||
}
|
||||
return hands
|
||||
}
|
||||
|
||||
func toCard(j rune) Card {
|
||||
switch j {
|
||||
case '2':
|
||||
return Two
|
||||
case '3':
|
||||
return Three
|
||||
case '4':
|
||||
return Four
|
||||
case '5':
|
||||
return Five
|
||||
case '6':
|
||||
return Six
|
||||
case '7':
|
||||
return Seven
|
||||
case '8':
|
||||
return Eight
|
||||
case '9':
|
||||
return Nine
|
||||
case 'T':
|
||||
return Ten
|
||||
case 'J':
|
||||
return Jack
|
||||
case 'Q':
|
||||
return Queen
|
||||
case 'K':
|
||||
return King
|
||||
case 'A':
|
||||
return Ace
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func toHandType(part int, cards [5]Card) HandType {
|
||||
jokers := 0
|
||||
handType := HighCard
|
||||
cardMap := make(map[Card]int)
|
||||
for _, card := range cards {
|
||||
if part == 2 && card == Jack {
|
||||
jokers++
|
||||
} else {
|
||||
if _, ok := cardMap[card]; ok {
|
||||
cardMap[card]++
|
||||
} else {
|
||||
cardMap[card] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
cardSorted := ToSortedSlice(cardMap)
|
||||
if part == 2 && jokers == 5 { return FiveKind}
|
||||
if part == 2 && jokers > 0 {
|
||||
cardSorted[0].Value = cardSorted[0].Value + jokers
|
||||
}
|
||||
if cardSorted[0].Value == 5 { handType = FiveKind}
|
||||
if cardSorted[0].Value == 4 { handType = FourKind}
|
||||
if cardSorted[0].Value == 3 {
|
||||
if cardSorted[1].Value == 2 {handType = FullHouse}
|
||||
if cardSorted[1].Value == 1 {handType = ThreeKind}
|
||||
}
|
||||
if cardSorted[0].Value == 2 {
|
||||
if cardSorted[1].Value == 2 {handType = TwoPair}
|
||||
if cardSorted[1].Value == 1 {handType = OnePair}
|
||||
}
|
||||
return handType
|
||||
}
|
||||
|
||||
//func toHandType(part int, cards [5]Card) HandType {
|
||||
// cardMap := make(map[Card]int)
|
||||
// for _, card := range cards {
|
||||
// if _, ok := cardMap[card]; ok {
|
||||
// cardMap[card]++
|
||||
// } else {
|
||||
// cardMap[card] = 1
|
||||
// }
|
||||
// }
|
||||
// if part == 2 {
|
||||
// switch cardMap[Jack] {
|
||||
// case 5:
|
||||
// return FiveKind
|
||||
// case 4:
|
||||
// return FiveKind
|
||||
// case 3:
|
||||
// if len(cardMap) == 2 {return FiveKind}
|
||||
// return FourKind
|
||||
// case 2:
|
||||
// switch len(cardMap) {
|
||||
// case 2:
|
||||
// return FiveKind
|
||||
// case 3:
|
||||
// return FourKind
|
||||
// case 4:
|
||||
// return ThreeKind
|
||||
//
|
||||
// }
|
||||
// case 1:
|
||||
// switch len(cardMap) {
|
||||
// case 2:
|
||||
// return FiveKind
|
||||
// case 3:
|
||||
// max := utils.MapFindMax(cardMap)
|
||||
// if max == 3 {return FourKind}
|
||||
// if max == 2 {return FullHouse}
|
||||
// case 4:
|
||||
// return ThreeKind
|
||||
// case 5:
|
||||
// return OnePair
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// switch len(cardMap) {
|
||||
// case 5:
|
||||
// return HighCard
|
||||
// case 4:
|
||||
// return OnePair
|
||||
// case 3:
|
||||
// for _, count := range cardMap {
|
||||
// if count == 3 {
|
||||
// return ThreeKind
|
||||
// }
|
||||
// }
|
||||
// return TwoPair
|
||||
// case 2:
|
||||
// for _, count := range cardMap {
|
||||
// if count == 4 {
|
||||
// return FourKind
|
||||
// }
|
||||
// }
|
||||
// return FullHouse
|
||||
// case 1:
|
||||
// return FiveKind
|
||||
// }
|
||||
// return -1
|
||||
//}
|
||||
|
||||
// KeyValue is a struct to hold key-value pairs
|
||||
type KeyValue struct {
|
||||
Key Card
|
||||
Value int
|
||||
}
|
||||
|
||||
func ToSortedSlice(myMap map[Card]int) []KeyValue {
|
||||
|
||||
var keyValuePairs []KeyValue
|
||||
for key, value := range myMap {
|
||||
keyValuePairs = append(keyValuePairs, KeyValue{key, value})
|
||||
}
|
||||
|
||||
// Sort the slice by values
|
||||
sort.Slice(keyValuePairs, func(i, j int) bool {
|
||||
if keyValuePairs[i].Value == keyValuePairs[j].Value { return keyValuePairs[i].Key > keyValuePairs[j].Key }
|
||||
return keyValuePairs[i].Value > keyValuePairs[j].Value
|
||||
})
|
||||
|
||||
// Create a new map with sorted key-value pairs
|
||||
//sortedMap := make(map[Card]int)
|
||||
//for _, kv := range keyValuePairs {
|
||||
// sortedMap[kv.Key] = kv.Value
|
||||
//}
|
||||
return keyValuePairs
|
||||
}
|
||||
33
2023/go/day07/day07_test.go
Normal file
33
2023/go/day07/day07_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package day07
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPart1(t *testing.T) {
|
||||
r := Part1(
|
||||
`32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483`)
|
||||
require.Equal(t, 6440, r)
|
||||
}
|
||||
|
||||
func TestPart2(t *testing.T) {
|
||||
r := Part2(
|
||||
`32T3K 765
|
||||
T55J5 684
|
||||
KK677 28
|
||||
KTJJT 220
|
||||
QQQJA 483`)
|
||||
require.Equal(t, 5905, r)
|
||||
}
|
||||
func TestPart21(t *testing.T) {
|
||||
r := Part2(
|
||||
`QQKKJ 765
|
||||
JKKK2 684`)
|
||||
require.Equal(t, 5905, r)
|
||||
}
|
||||
1000
2023/go/day07/input.txt
Normal file
1000
2023/go/day07/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ import (
|
||||
"adventofcode2023/day04"
|
||||
"adventofcode2023/day05"
|
||||
"adventofcode2023/day06"
|
||||
"adventofcode2023/day07"
|
||||
)
|
||||
// Usage: go run main.go <NN>
|
||||
// assumes input is in day<NN>/input.txt
|
||||
@@ -39,6 +40,9 @@ func main() {
|
||||
case 6:
|
||||
fmt.Printf("part 1: %d\n", day06.Part1(utils.Readfile(d)))
|
||||
fmt.Printf("part 2: %d\n", day06.Part2(utils.Readfile(d)))
|
||||
case 7:
|
||||
fmt.Printf("part 1: %d\n", day07.Part1(utils.Readfile(d)))
|
||||
fmt.Printf("part 2: %d\n", day07.Part2(utils.Readfile(d)))
|
||||
default:
|
||||
panic(fmt.Errorf("no such day: %d", d))
|
||||
}
|
||||
@@ -46,7 +50,7 @@ func main() {
|
||||
|
||||
// Reads day from os.Args.
|
||||
func day() int {
|
||||
latest := 5
|
||||
latest := 6
|
||||
if len(os.Args) == 1 {
|
||||
return latest
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user