Alexander Avery
1 year ago
2 changed files with 1183 additions and 0 deletions
@ -0,0 +1,183 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"bufio" |
||||
|
"fmt" |
||||
|
"io" |
||||
|
"sort" |
||||
|
"strconv" |
||||
|
) |
||||
|
|
||||
|
type day07 struct{} |
||||
|
|
||||
|
type rank int |
||||
|
|
||||
|
const ( |
||||
|
highCard rank = iota |
||||
|
onePair |
||||
|
twoPair |
||||
|
threeOfAKind |
||||
|
fullHouse |
||||
|
fourOfAKind |
||||
|
fiveOfAKind |
||||
|
) |
||||
|
|
||||
|
type hand struct { |
||||
|
cards []rune |
||||
|
values []int |
||||
|
rank rank |
||||
|
bid int |
||||
|
} |
||||
|
|
||||
|
type hands []hand |
||||
|
|
||||
|
func (h hands) Len() int { |
||||
|
return len(h) |
||||
|
} |
||||
|
|
||||
|
func (h hands) Less(i, j int) bool { |
||||
|
h1 := h[i] |
||||
|
h2 := h[j] |
||||
|
|
||||
|
if h1.rank < h2.rank { |
||||
|
return true |
||||
|
} else if h1.rank > h2.rank { |
||||
|
return false |
||||
|
} else { |
||||
|
for k := 0; k < 5; k++ { |
||||
|
if h1.values[k] < h2.values[k] { |
||||
|
return true |
||||
|
} else if h1.values[k] > h2.values[k] { |
||||
|
return false |
||||
|
} |
||||
|
} |
||||
|
panic("not reachable") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (h hands) Swap(i, j int) { |
||||
|
h[i], h[j] = h[j], h[i] |
||||
|
} |
||||
|
|
||||
|
// returns the rank and values of the hand
|
||||
|
func camelrank(hand hand) (rank, []int) { |
||||
|
counts := make([]int, 14) |
||||
|
hand.values = make([]int, len(hand.cards)) |
||||
|
|
||||
|
for i, r := range hand.cards { |
||||
|
switch r { |
||||
|
case '1': |
||||
|
counts[0] = counts[0] + 1 |
||||
|
hand.values[i] = 1 |
||||
|
case '2': |
||||
|
counts[1] = counts[1] + 1 |
||||
|
hand.values[i] = 2 |
||||
|
case '3': |
||||
|
counts[2] = counts[2] + 1 |
||||
|
hand.values[i] = 3 |
||||
|
case '4': |
||||
|
counts[3] = counts[3] + 1 |
||||
|
hand.values[i] = 4 |
||||
|
case '5': |
||||
|
counts[4] = counts[4] + 1 |
||||
|
hand.values[i] = 5 |
||||
|
case '6': |
||||
|
counts[5] = counts[5] + 1 |
||||
|
hand.values[i] = 6 |
||||
|
case '7': |
||||
|
counts[6] = counts[6] + 1 |
||||
|
hand.values[i] = 7 |
||||
|
case '8': |
||||
|
counts[7] = counts[7] + 1 |
||||
|
hand.values[i] = 8 |
||||
|
case '9': |
||||
|
counts[8] = counts[8] + 1 |
||||
|
hand.values[i] = 9 |
||||
|
case 'T': |
||||
|
counts[9] = counts[9] + 1 |
||||
|
hand.values[i] = 10 |
||||
|
case 'J': |
||||
|
counts[10] = counts[10] + 1 |
||||
|
hand.values[i] = 11 |
||||
|
case 'Q': |
||||
|
counts[11] = counts[11] + 1 |
||||
|
hand.values[i] = 12 |
||||
|
case 'K': |
||||
|
counts[12] = counts[12] + 1 |
||||
|
hand.values[i] = 13 |
||||
|
case 'A': |
||||
|
counts[13] = counts[13] + 1 |
||||
|
hand.values[i] = 14 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
var ( |
||||
|
seenPair bool |
||||
|
seenThreeOfAKind bool |
||||
|
) |
||||
|
|
||||
|
for _, count := range counts { |
||||
|
switch count { |
||||
|
case 0: |
||||
|
case 1: |
||||
|
continue |
||||
|
case 2: |
||||
|
if seenPair { |
||||
|
return twoPair, hand.values |
||||
|
} else if seenThreeOfAKind { |
||||
|
return fullHouse, hand.values |
||||
|
} |
||||
|
seenPair = true |
||||
|
case 3: |
||||
|
if seenPair { |
||||
|
return fullHouse, hand.values |
||||
|
} |
||||
|
seenThreeOfAKind = true |
||||
|
case 4: |
||||
|
return fourOfAKind, hand.values |
||||
|
case 5: |
||||
|
return fiveOfAKind, hand.values |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if seenPair { |
||||
|
return onePair, hand.values |
||||
|
} else if seenThreeOfAKind { |
||||
|
return threeOfAKind, hand.values |
||||
|
} |
||||
|
|
||||
|
return highCard, hand.values |
||||
|
} |
||||
|
|
||||
|
func (d day07) solve1(r io.Reader) string { |
||||
|
total := 0 |
||||
|
var hands hands = make([]hand, 0) |
||||
|
scanner := bufio.NewScanner(r) |
||||
|
scanner.Split(bufio.ScanWords) |
||||
|
|
||||
|
for i, w := 0, 0; scanner.Scan(); w++ { |
||||
|
word := scanner.Text() |
||||
|
if w%2 == 0 { |
||||
|
hand := hand{cards: []rune(word)} |
||||
|
hand.rank, hand.values = camelrank(hand) |
||||
|
hands = append(hands, hand) |
||||
|
} else { |
||||
|
val, err := strconv.ParseInt(word, 10, 64) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
hands[i].bid = int(val) |
||||
|
i++ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
sort.Sort(hands) |
||||
|
for i, hand := range hands { |
||||
|
total += hand.bid * (i + 1) |
||||
|
} |
||||
|
return fmt.Sprintf("%d", total) |
||||
|
} |
||||
|
|
||||
|
func (d day07) solve2(r io.Reader) string { |
||||
|
return "incomplete" |
||||
|
} |
File diff suppressed because it is too large
Loading…
Reference in new issue