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