Alexander Avery
11 months 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