part-01.scm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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-syntax ->
  15. (syntax-rules ()
  16. ;; first expression is left unchanged
  17. [(-> expr) expr]
  18. ;; take from the back, wrap other calls
  19. [(-> expr* ... (op args* ...))
  20. (op args* ... (-> expr* ...))]
  21. ;; make parens unnecessary in trivial case of no further arguments
  22. [(-> expr* ... op)
  23. (op (-> expr* ...))]))
  24. (define-syntax define-mapped
  25. (syntax-rules ()
  26. [(_ name body-expr)
  27. (define name
  28. (λ (arg)
  29. (map (λ (one)
  30. (body-expr one))
  31. arg)))]))
  32. (define split-list
  33. (λ (lst pred)
  34. (let iter ([lst° lst]
  35. [cont (λ (acc-split-off remaining)
  36. (values acc-split-off remaining))])
  37. (cond
  38. [(null? lst°)
  39. (cont '() '())]
  40. [(pred (car lst°))
  41. (cont '() (cdr lst°))]
  42. [else
  43. (iter (cdr lst°)
  44. (λ (split-off remaining)
  45. (cont (cons (car lst°) split-off)
  46. remaining)))]))))
  47. (define split-stack-config-string
  48. (λ (str)
  49. ;; |0123456789
  50. ;; |[T] [L] [D] [G] [P] [P] [V] [N] [R]
  51. (let ([positions '(1 5 9 13 17 21 25 29 33)])
  52. (map (λ (pos) (substring str pos (+ pos 1)))
  53. positions))))
  54. (define transpose
  55. (λ (mat)
  56. (let iter ([mat° mat] [transposed '()])
  57. (cond
  58. [(null? (car mat°)) transposed]
  59. [else
  60. (iter (map (λ (row) (cdr row)) mat°)
  61. (cons (map (λ (row) (car row)) mat°) transposed))]))))
  62. ;; MOVE abstraction
  63. (define execute-move
  64. (λ (move stacks)
  65. (let ([from (move-from move)]
  66. [to (move-to move)])
  67. (let iter ([stack-index 1]
  68. [stacks° stacks])
  69. (cond
  70. [(null? stacks°) '()]
  71. [(= stack-index from)
  72. (cons (cdr (list-ref stacks (- from 1)))
  73. (iter (+ stack-index 1)
  74. (drop stacks° 1)))]
  75. [(= stack-index to)
  76. (cons (cons (car (list-ref stacks (- from 1)))
  77. (list-ref stacks (- to 1)))
  78. (iter (+ stack-index 1)
  79. (drop stacks° 1)))]
  80. [else
  81. (cons (car stacks°)
  82. (iter (+ stack-index 1)
  83. (cdr stacks°)))])))))
  84. (define make-move
  85. (λ (from to)
  86. (cons from to)))
  87. (define move-from
  88. (λ (move)
  89. (car move)))
  90. (define move-to
  91. (λ (move)
  92. (cdr move)))
  93. (define run-moves
  94. (λ (move-str stacks)
  95. (display (simple-format #f "running move: ~a\n" move-str))
  96. (match (string-split move-str #\space)
  97. [(_1 amount-str _2 from-str _3 to-str)
  98. (let ([amount (string->number amount-str)]
  99. [from (string->number from-str)]
  100. [to (string->number to-str)])
  101. (let iter ([counter 0] [stacks° stacks])
  102. (cond
  103. [(< counter amount)
  104. (iter (+ counter 1)
  105. (execute-move (make-move from to)
  106. stacks°))]
  107. [else stacks°])))]
  108. [_ (error "unrecognized move")])))
  109. (define lines (get-lines-from-file "input"))
  110. (define-values (stacks-config moves) (split-list lines string-null?))
  111. (define initial-stacks
  112. (reverse
  113. (map (λ (stack)
  114. (filter (λ (elem)
  115. (and (not (string=? " " elem))
  116. (not (string->number elem))))
  117. stack))
  118. (transpose
  119. (map split-stack-config-string stacks-config)))))
  120. (pretty-print initial-stacks)
  121. (define final-stacks
  122. (let iter ([moves° moves] [stacks° initial-stacks])
  123. (cond
  124. [(null? moves°) stacks°]
  125. [else
  126. (iter (cdr moves°)
  127. (run-moves (car moves°)
  128. stacks°))])))
  129. (pretty-print final-stacks)
  130. (pretty-print (string-join (map (λ (stack) (car stack)) final-stacks) ""))