summaryrefslogtreecommitdiff
path: root/2023/Go/internal/day_07/part_01
diff options
context:
space:
mode:
Diffstat (limited to '2023/Go/internal/day_07/part_01')
-rw-r--r--2023/Go/internal/day_07/part_01/part_01.go273
-rw-r--r--2023/Go/internal/day_07/part_01/part_01_test.go432
2 files changed, 0 insertions, 705 deletions
diff --git a/2023/Go/internal/day_07/part_01/part_01.go b/2023/Go/internal/day_07/part_01/part_01.go
deleted file mode 100644
index a485dfd..0000000
--- a/2023/Go/internal/day_07/part_01/part_01.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package part_01
-
-import (
- "os"
- "strconv"
- "strings"
-)
-
-const USE_SAMPLE = false
-
-type handType int
-
-const (
- HIGH_CARD handType = iota
- PAIR
- TWO_PAIR
- THREE_OF_A_KIND
- FULL_HOUSE
- FOUR_OF_A_KIND
- FIVE_OF_A_KIND
-)
-
-func (h handType) String() string {
- return [...]string{"HIGH_CARD", "PAIR", "TWO_PAIR", "THREE_OF_A_KIND", "FULL_HOUSE", "FOUR_OF_A_KIND", "FIVE_OF_A_KIND"}[h]
-}
-
-type cardType int
-
-const (
- TWO cardType = iota
- THREE
- FOUR
- FIVE
- SIX
- SEVEN
- EIGHT
- NINE
- TEN
- JACK
- QUEEN
- KING
- ACE
-)
-
-func (c cardType) String() string {
- return [...]string{"TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN", "JACK", "QUEEN", "KING", "ACE"}[c]
-}
-
-type hand struct {
- strength handType
- cards []cardType
- bet int
-}
-
-/**
- * Tried:
- * - 252489894 (too high)
- * - 229176554 (too low)
- * - 200253108 (too low)
- */
-func Solve() {
- var filePath string
- if USE_SAMPLE {
- filePath = "../_input/day_07_part_01_sample.txt"
- } else {
- filePath = "../_input/day_07.txt"
- }
- contents, err := os.ReadFile(filePath)
- if err != nil {
- panic(err)
- }
-
- lines := strings.Split(string(contents), "\r\n")
- var hands []hand
- for _, line := range lines {
- if line == "" {
- continue
- }
-
- hands = append(hands, parseLine(line))
- }
-
- mappedByStrength := mapByStrength(hands)
-
- sortedByHighest := make(map[handType][]hand)
- for _, strength := range []handType{HIGH_CARD, PAIR, TWO_PAIR, THREE_OF_A_KIND, FULL_HOUSE, FOUR_OF_A_KIND, FIVE_OF_A_KIND} {
- if _, ok := mappedByStrength[strength]; !ok {
- continue
- }
-
- toBeSorted := mappedByStrength[strength]
- sortedByHighest[strength] = sortByHighest(toBeSorted)
- }
-
- flattened := flatten(sortedByHighest)
-
- answer := calculateWinnings(flattened)
-
- println("Answer: ", answer)
-}
-
-func parseLine(line string) hand {
- parts := strings.Split(line, " ")
-
- unparsedCards := strings.Split(parts[0], "")
- cards := parseCards(unparsedCards)
- strength := calculateStrength(cards)
-
- bet, err := strconv.Atoi(parts[1])
- if err != nil {
- panic(err)
- }
-
- return hand{
- strength,
- cards,
- bet,
- }
-}
-
-func parseCards(unparsedCards []string) []cardType {
- var cards []cardType
- for _, card := range unparsedCards {
- switch card {
- case "2":
- cards = append(cards, TWO)
- case "3":
- cards = append(cards, THREE)
- case "4":
- cards = append(cards, FOUR)
- case "5":
- cards = append(cards, FIVE)
- case "6":
- cards = append(cards, SIX)
- case "7":
- cards = append(cards, SEVEN)
- case "8":
- cards = append(cards, EIGHT)
- case "9":
- cards = append(cards, NINE)
- case "T":
- cards = append(cards, TEN)
- case "J":
- cards = append(cards, JACK)
- case "Q":
- cards = append(cards, QUEEN)
- case "K":
- cards = append(cards, KING)
- case "A":
- cards = append(cards, ACE)
- }
- }
- return cards
-}
-
-func calculateStrength(cards []cardType) handType {
- strength := map[cardType]int{}
- for _, card := range cards {
- if _, ok := strength[card]; !ok {
- strength[card] = 0
- }
- strength[card]++
- }
-
- var pairs int
- var hasThreeOfAKind bool
- for _, count := range strength {
- if count == 5 {
- return FIVE_OF_A_KIND
- }
-
- if count == 4 {
- return FOUR_OF_A_KIND
- }
-
- if count == 3 {
- hasThreeOfAKind = true
- }
-
- if count == 2 {
- pairs++
- }
- }
-
- if hasThreeOfAKind && pairs == 1 {
- return FULL_HOUSE
- }
-
- if hasThreeOfAKind {
- return THREE_OF_A_KIND
- }
-
- if pairs == 2 {
- return TWO_PAIR
- }
-
- if pairs == 1 {
- return PAIR
- }
-
- return HIGH_CARD
-}
-
-func mapByStrength(hands []hand) map[handType][]hand {
-
- handsByStrength := make(map[handType][]hand)
- for _, hand := range hands {
- handsByStrength[hand.strength] = append(handsByStrength[hand.strength], hand)
- }
-
- return handsByStrength
-}
-
-// low to high
-func sortByHighest(hands []hand) []hand {
- var partition = func(arr []hand, low, high int) ([]hand, int) {
- pivot := arr[high]
- index := low
-
- for i := low; i < high; i++ {
- // Always 5 cards
- for j := 0; j < 5; j++ {
- if arr[i].cards[j] < pivot.cards[j] {
- arr[i], arr[index] = arr[index], arr[i]
- index++
- break
- }
-
- if arr[i].cards[j] != pivot.cards[j] {
- break
- }
- }
- }
-
- arr[high], arr[index] = arr[index], arr[high]
-
- return arr, index
- }
-
- var quickSort func(arr []hand, low, high int) []hand
- quickSort = func(arr []hand, low, high int) []hand {
- if low < high {
- arr, pivot := partition(arr, low, high)
-
- quickSort(arr, low, pivot-1)
- quickSort(arr, pivot+1, high)
- }
-
- return arr
- }
-
- hands = quickSort(hands, 0, len(hands)-1)
-
- return hands
-}
-
-func flatten(hands map[handType][]hand) []hand {
- var flat []hand
- for _, handType := range []handType{HIGH_CARD, PAIR, TWO_PAIR, THREE_OF_A_KIND, FULL_HOUSE, FOUR_OF_A_KIND, FIVE_OF_A_KIND} {
- flat = append(flat, hands[handType]...)
- }
- return flat
-}
-
-func calculateWinnings(hands []hand) int {
- var winnings int
- for i, hand := range hands {
- earned := hand.bet * (i + 1)
- winnings += earned
- println("hand ", i, ": { strength: ", hand.strength.String(), ", cards: [", hand.cards[0], hand.cards[1], hand.cards[2], hand.cards[3], hand.cards[4], "], earned: ", earned, " }")
- }
- return winnings
-}
diff --git a/2023/Go/internal/day_07/part_01/part_01_test.go b/2023/Go/internal/day_07/part_01/part_01_test.go
deleted file mode 100644
index 6ceabe8..0000000
--- a/2023/Go/internal/day_07/part_01/part_01_test.go
+++ /dev/null
@@ -1,432 +0,0 @@
-package part_01
-
-import "testing"
-
-func TestParseLine(t *testing.T) {
- tests := map[string]struct {
- input string
- expected hand
- }{
- "sample_1": {
- input: "32T3K 765",
- expected: hand{
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- },
- "sample_2": {
- input: "T55J5 684",
- expected: hand{
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- },
- "sample_3": {
- input: "KK677 28",
- expected: hand{
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- },
- "sample_4": {
- input: "KTJJT 220",
- expected: hand{
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- },
- "sample_5": {
- input: "QQQJA 483",
- expected: hand{
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- "full_house": {
- input: "QQQAA 999",
- expected: hand{
- strength: FULL_HOUSE,
- cards: []cardType{QUEEN, QUEEN, QUEEN, ACE, ACE},
- bet: 999,
- },
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- actual := parseLine(test.input)
-
- if actual.strength != test.expected.strength {
- t.Errorf("Strength: expected %v, got %v", test.expected.strength, actual.strength)
- }
-
- if len(actual.cards) != len(test.expected.cards) {
- t.Errorf("Cards: expected %v, got %v", test.expected.cards, actual.cards)
- }
-
- for i, card := range actual.cards {
- if card != test.expected.cards[i] {
- t.Errorf("Card Order: expected %v, got %v", test.expected.cards, actual.cards)
- }
- }
-
- if actual.bet != test.expected.bet {
- t.Errorf("Bet: expected %v, got %v", test.expected.bet, actual.bet)
- }
- })
- }
-}
-
-func TestMapByStrength(t *testing.T) {
- tests := map[string]struct {
- input []hand
- expected map[handType][]hand
- }{
- "sample": {
- input: []hand{
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- expected: map[handType][]hand{
- PAIR: {
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- },
- TWO_PAIR: {
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- },
- THREE_OF_A_KIND: {
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- },
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- actual := mapByStrength(test.input)
-
- for strength, hands := range actual {
- expected := test.expected[strength]
-
- if len(hands) != len(expected) {
- t.Errorf("Length: expected %v, got %v", len(expected), len(hands))
- }
-
- for i, hand := range hands {
- if hand.strength != expected[i].strength {
- t.Errorf("Strength: expected %v, got %v", expected[i].strength, hand.strength)
- }
-
- if len(hand.cards) != len(expected[i].cards) {
- t.Errorf("Cards: expected %v, got %v", expected[i].cards, hand.cards)
- }
-
- for j, card := range hand.cards {
- if card != expected[i].cards[j] {
- t.Errorf("Card Order: expected %v, got %v", expected[i].cards, hand.cards)
- }
- }
-
- if hand.bet != expected[i].bet {
- t.Errorf("Bet: expected %v, got %v", expected[i].bet, hand.bet)
- }
- }
- }
- })
- }
-}
-
-func TestSortByHighest(t *testing.T) {
- tests := map[string]struct {
- input []hand
- expected []hand
- }{
- "sample": {
- input: []hand{
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- expected: []hand{
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- },
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- actual := sortByHighest(test.input)
-
- if len(actual) != len(test.expected) {
- t.Errorf("Length: expected %v, got %v", len(test.expected), len(actual))
- }
-
- for i, hand := range actual {
- if hand.strength != test.expected[i].strength {
- t.Errorf("Strength: expected %v, got %v", test.expected[i].strength, hand.strength)
- }
-
- if len(hand.cards) != len(test.expected[i].cards) {
- t.Errorf("Cards: expected %v, got %v", test.expected[i].cards, hand.cards)
- }
-
- for j, card := range hand.cards {
- if card != test.expected[i].cards[j] {
- t.Errorf("Card Order: expected %v, got %v", test.expected[i].cards, hand.cards)
- }
- }
-
- if hand.bet != test.expected[i].bet {
- t.Errorf("Bet: expected %v, got %v", test.expected[i].bet, hand.bet)
- }
- }
- })
- }
-}
-
-func TestFlatten(t *testing.T) {
- tests := map[string]struct {
- input map[handType][]hand
- expected []hand
- }{
- "sample": {
- // Order jumbled to ensure sorting works
- input: map[handType][]hand{
- TWO_PAIR: {
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- },
- PAIR: {
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- },
- THREE_OF_A_KIND: {
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- },
- expected: []hand{
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- actual := flatten(test.input)
-
- if len(actual) != len(test.expected) {
- t.Errorf("Length: expected %v, got %v", len(test.expected), len(actual))
- }
-
- for i, hand := range actual {
- expected := test.expected[i]
-
- if hand.strength != expected.strength {
- t.Errorf("Strength: expected %v, got %v", expected.strength, hand.strength)
- }
-
- if len(hand.cards) != len(expected.cards) {
- t.Errorf("Cards: expected %v, got %v", expected.cards, hand.cards)
- }
-
- for i, card := range hand.cards {
- if card != expected.cards[i] {
- t.Errorf("Card Order: expected %v, got %v", expected.cards, hand.cards)
- }
- }
-
- if hand.bet != expected.bet {
- t.Errorf("Bet: expected %v, got %v", expected.bet, hand.bet)
- }
- }
- })
- }
-}
-
-func TestCalculateWinnings(t *testing.T) {
- tests := map[string]struct {
- input []hand
- expected int
- }{
- "sample": {
- input: []hand{
- {
- strength: PAIR,
- cards: []cardType{THREE, TWO, TEN, THREE, KING},
- bet: 765,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, TEN, JACK, JACK, TEN},
- bet: 220,
- },
- {
- strength: TWO_PAIR,
- cards: []cardType{KING, KING, SIX, SEVEN, SEVEN},
- bet: 28,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{TEN, FIVE, FIVE, JACK, FIVE},
- bet: 684,
- },
- {
- strength: THREE_OF_A_KIND,
- cards: []cardType{QUEEN, QUEEN, QUEEN, JACK, ACE},
- bet: 483,
- },
- },
- expected: 6440,
- },
- }
-
- for name, test := range tests {
- t.Run(name, func(t *testing.T) {
- actual := calculateWinnings(test.input)
-
- if actual != test.expected {
- t.Errorf("Winnings: expected %v, got %v", test.expected, actual)
- }
- })
- }
-}