diff options
Diffstat (limited to '2023/Go/internal/day_07/part_01/part_01.go')
| -rw-r--r-- | 2023/Go/internal/day_07/part_01/part_01.go | 273 |
1 files changed, 0 insertions, 273 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 -} |
