code.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. )
  8. type move struct {
  9. quantity int
  10. from int
  11. to int
  12. }
  13. func parseBoxes(line string, boxes [][]byte) [][]byte {
  14. counter := 0
  15. index := 0
  16. readLetter := false
  17. for i := range line {
  18. if line[i] == '\n' {
  19. break
  20. }
  21. counter++
  22. if counter > 3 {
  23. index++
  24. counter = 0
  25. }
  26. if line[i] == '[' {
  27. readLetter = true
  28. continue
  29. }
  30. if line[i] == ']' {
  31. readLetter = false
  32. continue
  33. }
  34. if readLetter {
  35. edge := len(boxes) - 1
  36. if index > edge {
  37. for i := 0; i < index-edge; i++ {
  38. boxes = append(boxes, []byte{})
  39. }
  40. }
  41. boxes[index] = append(boxes[index], line[i])
  42. }
  43. }
  44. return boxes
  45. }
  46. func reverseBoxes(boxes [][]byte) [][]byte {
  47. for x := range boxes {
  48. for i, j := 0, len(boxes[x])-1; i < j; i, j = i+1, j-1 {
  49. boxes[x][i], boxes[x][j] = boxes[x][j], boxes[x][i]
  50. }
  51. }
  52. return boxes
  53. }
  54. func parseMove(line string) move {
  55. var current move
  56. n, err := fmt.Sscanf(line, "move %d from %d to %d", &current.quantity, &current.from, &current.to)
  57. if n != 3 || err != nil {
  58. log.Fatal("Can't parse move!", err)
  59. }
  60. return current
  61. }
  62. func readInput(file *os.File) ([][]byte, []move) {
  63. scanner := bufio.NewScanner(file)
  64. var moves []move
  65. var boxes [][]byte
  66. readBoxes := true
  67. for scanner.Scan() {
  68. line := scanner.Text()
  69. if line == "" {
  70. readBoxes = false
  71. continue
  72. }
  73. if readBoxes {
  74. boxes = parseBoxes(line, boxes)
  75. continue
  76. }
  77. moves = append(moves, parseMove(line))
  78. }
  79. return reverseBoxes(boxes), moves
  80. }
  81. func moveBox(boxes [][]byte, action move) [][]byte {
  82. last := len(boxes[action.from-1]) - 1
  83. letter := boxes[action.from-1][last]
  84. boxes[action.from-1] = boxes[action.from-1][:last]
  85. boxes[action.to-1] = append(boxes[action.to-1], letter)
  86. return boxes
  87. }
  88. func part1(boxes [][]byte, moves []move) string {
  89. for i := range moves {
  90. for j := 0; j < moves[i].quantity; j++ {
  91. moveBox(boxes, moves[i])
  92. }
  93. }
  94. var word []byte
  95. for i := range boxes {
  96. word = append(word, boxes[i][len(boxes[i])-1])
  97. }
  98. return string(word)
  99. }
  100. func main() {
  101. if len(os.Args) < 2 {
  102. log.Fatal("You need to specify a file!")
  103. }
  104. filePath := os.Args[1]
  105. file, err := os.Open(filePath)
  106. if err != nil {
  107. log.Fatalf("Failed to open %s!\n", filePath)
  108. }
  109. boxes, moves := readInput(file)
  110. fmt.Println("Part1:", part1(boxes, moves))
  111. }