day23.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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, iterations int) []int {
  64. index := 0
  65. size := len(sequence)
  66. length := size - 1
  67. for iteration := 0; iteration < iterations; iteration++ {
  68. pickup := getThreeCups(sequence, index+1)
  69. x := 0
  70. y := index + 1
  71. if y > length {
  72. y = 0
  73. }
  74. for x < 3 {
  75. sequence[y] = 0
  76. x++
  77. y++
  78. if y > length {
  79. y = 0
  80. }
  81. }
  82. destination := sequence[index] - 1
  83. for {
  84. if destination < min {
  85. _, newDestination := minMax(sequence)
  86. destination = newDestination
  87. break
  88. }
  89. if !inSequence(destination, pickup) {
  90. break
  91. }
  92. destination--
  93. }
  94. newSequence := make([]int, size)
  95. i := index + 1
  96. j := index + 4
  97. if j > length {
  98. j = j - size
  99. }
  100. count := 0
  101. for count < size {
  102. count++
  103. if i > length {
  104. i = 0
  105. }
  106. if j > length {
  107. j = 0
  108. }
  109. newSequence[i] = sequence[j]
  110. if sequence[j] == destination {
  111. i++
  112. for _, cup := range pickup {
  113. if i > length {
  114. i = 0
  115. }
  116. newSequence[i] = cup
  117. i++
  118. }
  119. count += 3
  120. j++
  121. continue
  122. }
  123. j++
  124. i++
  125. }
  126. sequence = newSequence
  127. index++
  128. if index > length {
  129. index = 0
  130. }
  131. }
  132. return sequence
  133. }
  134. func part1(sequence []int) string {
  135. size := len(sequence)
  136. indexOfOne := indexOf(1, sequence)
  137. var result []string
  138. for i := indexOfOne + 1; i < size; i++ {
  139. result = append(result, fmt.Sprintf("%d", sequence[i]))
  140. }
  141. for i := 0; i < indexOfOne; i++ {
  142. result = append(result, fmt.Sprintf("%d", sequence[i]))
  143. }
  144. return strings.Join(result, "")
  145. }
  146. func main() {
  147. if len(os.Args) < 2 {
  148. log.Fatal("You need to specify a sequence!")
  149. }
  150. sequence := processSequence(os.Args[1])
  151. min, max := minMax(sequence)
  152. finalSequence := getSequence(sequence, min, max, 100)
  153. fmt.Println("Part1:", part1(finalSequence))
  154. }