day23.go 2.8 KB

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