day23.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "os"
  6. "strconv"
  7. "strings"
  8. )
  9. func processSequence(input string) []int {
  10. var sequence []int
  11. for _, letter := range input {
  12. cup, err := strconv.Atoi(string(letter))
  13. if err != nil {
  14. log.Fatalf("Error processing cup for %s: %s", letter, err)
  15. }
  16. sequence = append(sequence, cup)
  17. }
  18. return sequence
  19. }
  20. func minMax(sequence []int) (int, int) {
  21. max := 0
  22. min := 9
  23. for _, cup := range sequence {
  24. if cup > max {
  25. max = cup
  26. }
  27. if cup < min {
  28. min = cup
  29. }
  30. }
  31. return min, max
  32. }
  33. func inSequence(value int, sequence []int) bool {
  34. for _, item := range sequence {
  35. if item == value {
  36. return true
  37. }
  38. }
  39. return false
  40. }
  41. func indexOf(value int, sequence []int) int {
  42. for i, item := range sequence {
  43. if item == value {
  44. return i
  45. }
  46. }
  47. return -1
  48. }
  49. func getThreeCups(sequence []int, index int) []int {
  50. count := 0
  51. length := len(sequence) - 1
  52. var cups []int
  53. for count < 3 {
  54. if index > length {
  55. index = 0
  56. }
  57. cups = append(cups, sequence[index])
  58. count++
  59. index++
  60. }
  61. return cups
  62. }
  63. func getSequence(sequence []int, min, max int) []int {
  64. index := 0
  65. size := len(sequence)
  66. for iterations := 0; iterations < 100; iterations++ {
  67. pickup := getThreeCups(sequence, index+1)
  68. x := 0
  69. y := index + 1
  70. if y > size-1 {
  71. y = 0
  72. }
  73. for x < 3 {
  74. sequence[y] = 0
  75. x++
  76. y++
  77. if y > size-1 {
  78. y = 0
  79. }
  80. }
  81. for j, _ := range sequence {
  82. if j > index && j < index+4 {
  83. sequence[j] = 0
  84. }
  85. }
  86. destination := sequence[index] - 1
  87. for {
  88. if destination < min {
  89. _, newDestination := minMax(sequence)
  90. destination = newDestination
  91. break
  92. }
  93. if !inSequence(destination, pickup) {
  94. break
  95. }
  96. destination--
  97. }
  98. newSequence := make([]int, size)
  99. i := index + 1
  100. j := index + 4
  101. if j > size-1 {
  102. j = j - size
  103. }
  104. count := 0
  105. for count < size {
  106. count++
  107. if i > size-1 {
  108. i = 0
  109. }
  110. if j > size-1 {
  111. j = 0
  112. }
  113. newSequence[i] = sequence[j]
  114. if sequence[j] == destination {
  115. i++
  116. for _, cup := range pickup {
  117. if i > size-1 {
  118. i = 0
  119. }
  120. newSequence[i] = cup
  121. i++
  122. }
  123. count += 3
  124. j++
  125. continue
  126. }
  127. j++
  128. i++
  129. }
  130. sequence = newSequence
  131. index++
  132. if index > size-1 {
  133. index = 0
  134. }
  135. }
  136. return sequence
  137. }
  138. func part1(sequence []int) string {
  139. size := len(sequence)
  140. indexOfOne := indexOf(1, sequence)
  141. var result []string
  142. for i := indexOfOne + 1; i < size; i++ {
  143. result = append(result, fmt.Sprintf("%d", sequence[i]))
  144. }
  145. for i := 0; i < indexOfOne; i++ {
  146. result = append(result, fmt.Sprintf("%d", sequence[i]))
  147. }
  148. return strings.Join(result, "")
  149. }
  150. func main() {
  151. if len(os.Args) < 2 {
  152. log.Fatal("You need to specify a sequence!")
  153. }
  154. sequence := processSequence(os.Args[1])
  155. min, max := minMax(sequence)
  156. finalSequence := getSequence(sequence, min, max)
  157. fmt.Println("Part1:", part1(finalSequence))
  158. }