code.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "sort"
  8. )
  9. const (
  10. NumberOfCards = 5
  11. NumberOfRanks = 13
  12. )
  13. type Hand struct {
  14. cards string
  15. bid int
  16. ranks [NumberOfCards]int
  17. score int
  18. }
  19. func (h *Hand) analyzeHand() {
  20. five := false
  21. four := false
  22. three := false
  23. pairs := 0
  24. var numberInRank [NumberOfRanks]int
  25. for i := range h.cards {
  26. numberInRank[ranks[h.cards[i]]]++
  27. h.ranks[i] = ranks[h.cards[i]]
  28. }
  29. for rank := 0; rank < NumberOfRanks; rank++ {
  30. switch numberInRank[rank] {
  31. case 5:
  32. five = true
  33. case 4:
  34. four = true
  35. case 3:
  36. three = true
  37. case 2:
  38. pairs++
  39. }
  40. }
  41. if five {
  42. h.score = FiveKind
  43. } else if four {
  44. h.score = FourKind
  45. } else if three && pairs == 1 {
  46. h.score = FullHouse
  47. } else if three {
  48. h.score = ThreeKind
  49. } else if pairs == 2 {
  50. h.score = TwoPair
  51. } else if pairs == 1 {
  52. h.score = OnePair
  53. } else {
  54. h.score = HighCard
  55. }
  56. }
  57. func readInput(file *os.File) []Hand {
  58. scanner := bufio.NewScanner(file)
  59. var hands []Hand
  60. for scanner.Scan() {
  61. line := scanner.Text()
  62. if line == "" {
  63. break
  64. }
  65. var hand Hand
  66. n, err := fmt.Sscanf(line, "%s %d", &hand.cards, &hand.bid)
  67. if n != 2 || err != nil {
  68. log.Fatalf("Failed to read hand: %s\n%s", line, err)
  69. }
  70. hand.analyzeHand()
  71. hands = append(hands, hand)
  72. }
  73. return hands
  74. }
  75. var ranks map[byte]int
  76. func init() {
  77. ranks = make(map[byte]int)
  78. ranks['2'] = 0
  79. ranks['3'] = 1
  80. ranks['4'] = 2
  81. ranks['5'] = 3
  82. ranks['6'] = 4
  83. ranks['7'] = 5
  84. ranks['8'] = 6
  85. ranks['9'] = 7
  86. ranks['T'] = 8
  87. ranks['J'] = 9
  88. ranks['Q'] = 10
  89. ranks['K'] = 11
  90. ranks['A'] = 12
  91. }
  92. const (
  93. HighCard = iota + 1
  94. OnePair
  95. TwoPair
  96. ThreeKind
  97. FullHouse
  98. FourKind
  99. FiveKind
  100. )
  101. func part1(hands []Hand) int {
  102. var result int
  103. sort.Slice(hands, func(i, j int) bool {
  104. if hands[i].score == hands[j].score {
  105. for k := 0; k < NumberOfCards; k++ {
  106. if hands[i].ranks[k] == hands[j].ranks[k] {
  107. continue
  108. }
  109. return hands[i].ranks[k] < hands[j].ranks[k]
  110. }
  111. }
  112. return hands[i].score < hands[j].score
  113. })
  114. for i := range hands {
  115. result += (i + 1) * hands[i].bid
  116. }
  117. return result
  118. }
  119. func main() {
  120. if len(os.Args) < 2 {
  121. log.Fatal("You need to specify a file!")
  122. }
  123. filePath := os.Args[1]
  124. file, err := os.Open(filePath)
  125. if err != nil {
  126. log.Fatalf("Failed to open %s!\n", filePath)
  127. }
  128. hands := readInput(file)
  129. fmt.Println("Part1:", part1(hands))
  130. }