part-02.scm 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. (import
  2. (except (rnrs base) let-values map)
  3. (only (guile)
  4. lambda* λ
  5. string-split
  6. string->number
  7. string-join)
  8. (fileio)
  9. (srfi srfi-1)
  10. (srfi srfi-8)
  11. (srfi srfi-11)
  12. (ice-9 pretty-print)
  13. (ice-9 match))
  14. (define split-list
  15. (λ (lst pred)
  16. (let iter ([lst° lst]
  17. [cont (λ (acc-split-off remaining)
  18. (values acc-split-off remaining))])
  19. (cond
  20. [(null? lst°)
  21. (cont '() '())]
  22. [(pred (car lst°))
  23. (cont '() (cdr lst°))]
  24. [else
  25. (iter (cdr lst°)
  26. (λ (split-off remaining)
  27. (cont (cons (car lst°) split-off)
  28. remaining)))]))))
  29. (define split-stack-config-string
  30. (λ (str)
  31. ;; |0123456789
  32. ;; |[T] [L] [D] [G] [P] [P] [V] [N] [R]
  33. (let ([positions '(1 5 9 13 17 21 25 29 33)])
  34. (map (λ (pos) (substring str pos (+ pos 1)))
  35. positions))))
  36. (define transpose
  37. (λ (mat)
  38. (let iter ([mat° mat] [transposed '()])
  39. (cond
  40. [(null? (car mat°)) transposed]
  41. [else
  42. (iter (map (λ (row) (cdr row)) mat°)
  43. (cons (map (λ (row) (car row)) mat°) transposed))]))))
  44. (define execute-move
  45. (λ (amount from to stacks)
  46. (let iter ([stack-index 1] [stacks° stacks])
  47. (cond
  48. [(null? stacks°) '()]
  49. [(= stack-index from)
  50. (cons (drop (first stacks°) amount)
  51. (iter (+ stack-index 1)
  52. (drop stacks° 1)))]
  53. [(= stack-index to)
  54. (cons (append (take (list-ref stacks (- from 1)) amount)
  55. (first stacks°))
  56. (iter (+ stack-index 1)
  57. (drop stacks° 1)))]
  58. [else
  59. (cons (first stacks°)
  60. (iter (+ stack-index 1)
  61. (drop stacks° 1)))]))))
  62. (define run-move
  63. (λ (move-str stacks)
  64. (display (simple-format #f "running move: ~a\n" move-str))
  65. (match (string-split move-str #\space)
  66. [(_1 amount-str _2 from-str _3 to-str)
  67. (let ([amount (string->number amount-str)]
  68. [from (string->number from-str)]
  69. [to (string->number to-str)])
  70. (execute-move amount from to stacks))]
  71. [_ (error "unrecognized move")])))
  72. (define lines (get-lines-from-file "input"))
  73. (define-values (stacks-config moves) (split-list lines string-null?))
  74. (define initial-stacks
  75. (reverse
  76. (map (λ (stack)
  77. (filter (λ (elem)
  78. (and (not (string=? " " elem))
  79. (not (string->number elem))))
  80. stack))
  81. (transpose
  82. (map split-stack-config-string stacks-config)))))
  83. (pretty-print initial-stacks)
  84. (define final-stacks
  85. (let iter ([moves° moves] [stacks° initial-stacks])
  86. (cond
  87. [(null? moves°) stacks°]
  88. [else
  89. (iter (cdr moves°)
  90. (run-move (car moves°)
  91. stacks°))])))
  92. (pretty-print final-stacks)
  93. (pretty-print (string-join (map (λ (stack) (car stack)) final-stacks) ""))