part-01.scm 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. (import
  2. (except (rnrs base) let-values map error)
  3. (only (guile)
  4. lambda* λ
  5. current-output-port)
  6. (fileio)
  7. (srfi srfi-1)
  8. ;; let-values
  9. (srfi srfi-11)
  10. ;; hash tables
  11. (srfi srfi-69)
  12. (ice-9 pretty-print))
  13. (define lines (get-lines-from-file "input"))
  14. (define num-rows (length lines))
  15. (define num-cols (string-length (first lines)))
  16. (define trees
  17. (let ([trees (make-array 0 num-rows num-cols)])
  18. (let iter-rows ([lines° lines] [row-ind 0])
  19. (cond
  20. [(null? lines°) trees]
  21. [else
  22. (let iter-cols ([numbers-line° (first lines°)]
  23. [col-ind 0])
  24. (unless (string-null? numbers-line°)
  25. (array-set! trees
  26. (string->number (substring numbers-line° 0 1))
  27. row-ind
  28. col-ind)
  29. (iter-cols (substring numbers-line° 1)
  30. (+ col-ind 1))))
  31. (iter-rows (drop lines° 1)
  32. (+ row-ind 1))]))))
  33. (define step-down
  34. (λ (row col)
  35. (values (+ row 1) col)))
  36. (define step-left
  37. (λ (row col)
  38. (values row (- col 1))))
  39. (define step-up
  40. (λ (row col)
  41. (values (- row 1) col)))
  42. (define step-right
  43. (λ (row col)
  44. (values row (+ col 1))))
  45. (define array-len-in-dim
  46. (λ (arr dim)
  47. (let* ([shape (array-shape arr)]
  48. [dim-min-max (list-ref shape dim)])
  49. (+ (- (second dim-min-max)
  50. (first dim-min-max))
  51. 1))))
  52. (define visible-in-direction?
  53. (λ (trees init-row-ind init-col-ind step)
  54. (let ([tree-height (array-ref trees init-row-ind init-col-ind)])
  55. ;; already step away 1 step towards the border
  56. (let-values ([(next-row-ind next-col-ind) (step init-row-ind init-col-ind)])
  57. (let iter ([row-ind° next-row-ind] [col-ind° next-col-ind])
  58. (cond
  59. [(array-in-bounds? trees row-ind° col-ind°)
  60. (if (>= (array-ref trees row-ind° col-ind°) tree-height)
  61. #f
  62. (let-values ([(next-row-ind next-col-ind) (step row-ind° col-ind°)])
  63. (iter next-row-ind next-col-ind)))]
  64. [else #t]))))))
  65. (define visible?
  66. (λ (trees row-ind col-ind)
  67. ;; idea: calculate number of directions in which tree is visible
  68. (or (visible-in-direction? trees row-ind col-ind step-up)
  69. (visible-in-direction? trees row-ind col-ind step-right)
  70. (visible-in-direction? trees row-ind col-ind step-down)
  71. (visible-in-direction? trees row-ind col-ind step-left))))
  72. (define calc-tree-visibility
  73. (λ (trees)
  74. (let* ([rows (array-len-in-dim trees 0)]
  75. [cols (array-len-in-dim trees 1)]
  76. [visibility (make-array 0 rows cols)]
  77. [max-row-ind (- rows 1)]
  78. [max-col-ind (- cols 1)])
  79. (let iter-rows ([row-ind° 0])
  80. (cond
  81. [(<= row-ind° max-row-ind)
  82. (let iter-cols ([col-ind° 0])
  83. (cond
  84. ;; go to next row
  85. [(<= col-ind° max-col-ind)
  86. (cond
  87. [(visible? trees row-ind° col-ind°)
  88. (simple-format (current-output-port) "r:~a,c:~a is visibile\n" row-ind° col-ind°)
  89. (array-set! visibility 1 row-ind° col-ind°)
  90. (iter-cols (+ col-ind° 1))]
  91. [else
  92. (iter-cols (+ col-ind° 1))])]
  93. [else
  94. (iter-rows (+ row-ind° 1))]))]
  95. [else visibility])))))
  96. (simple-format (current-output-port)
  97. "~a\n"
  98. (apply
  99. +
  100. (map (λ (row) (apply + row))
  101. (array->list (calc-tree-visibility trees)))))
  102. ;; (define count-in-direction
  103. ;; (λ (trees start-row-ind start-col-ind next already-seen-table)
  104. ;; (let ([rows (array-len-in-dim trees 0)]
  105. ;; [cols (array-len-in-dim trees 1)])
  106. ;; (let iter ([row-ind start-row-ind]
  107. ;; [col-ind start-col-ind]
  108. ;; [max-tree-height° -1]
  109. ;; [counter 0])
  110. ;; (cond
  111. ;; [(>= col-ind cols) counter]
  112. ;; [(< col-ind 0) counter]
  113. ;; [(>= row-ind rows) counter]
  114. ;; [(< row-ind 0) counter]
  115. ;; [else
  116. ;; (let ([current-tree-height (array-ref trees row-ind col-ind)])
  117. ;; (cond
  118. ;; [(> current-tree-height max-tree-height°)
  119. ;; (let-values ([(next-row-ind next-col-ind) (next row-ind col-ind)])
  120. ;; (hash-table-ref table key [default-thunk])
  121. ;; ;; (cond
  122. ;; ;; [(hash-table-ref/default already-seen-table (cons row-ind col-ind) #f)
  123. ;; ;; (iter next-row-ind
  124. ;; ;; next-col-ind
  125. ;; ;; current-tree-height
  126. ;; ;; (+ counter 1))
  127. ;; ;; ]
  128. ;; ;; [else ...])
  129. ;; )]
  130. ;; [else
  131. ;; (let-values ([(next-row-ind next-col-ind) (next row-ind col-ind)])
  132. ;; (iter next-row-ind
  133. ;; next-col-ind
  134. ;; max-tree-height°
  135. ;; counter))]))])))))
  136. ;; (define count-from-side
  137. ;; (λ (trees
  138. ;; start-row-ind start-col-ind
  139. ;; max-row-ind max-col-ind
  140. ;; next-line
  141. ;; next-tree
  142. ;; already-seen-table)
  143. ;; (let ([rows (array-len-in-dim trees 0)]
  144. ;; [cols (array-len-in-dim trees 0)])
  145. ;; (let iter ([row-ind start-row-ind]
  146. ;; [col-ind start-col-ind]
  147. ;; [counter 0])
  148. ;; (cond
  149. ;; ;; in bounds check
  150. ;; [(and (<= row-ind max-row-ind)
  151. ;; (>= row-ind 0)
  152. ;; (<= col-ind max-col-ind)
  153. ;; (>= col-ind 0))
  154. ;; (simple-format (current-output-port) "starting at: r=~a,c=~a\n" row-ind col-ind)
  155. ;; ;; Calculate the starting point of the next line to count
  156. ;; ;; visible trees in.
  157. ;; (let-values ([(next-row-ind next-col-ind) (next-line row-ind col-ind)])
  158. ;; (iter next-row-ind
  159. ;; next-col-ind
  160. ;; (+ counter
  161. ;; (count-in-direction trees
  162. ;; row-ind
  163. ;; col-ind
  164. ;; next-tree
  165. ;; already-seen-table))))]
  166. ;; [else counter])))))
  167. ;; (define count-trees
  168. ;; (λ (trees)
  169. ;; (let ([rows (array-len-in-dim trees 0)]
  170. ;; [cols (array-len-in-dim trees 0)]
  171. ;; [already-seen-table (make-hash-table equal?)])
  172. ;; (simple-format (current-output-port) "rows: ~a\n" rows)
  173. ;; (simple-format (current-output-port) "cols: ~a\n" cols)
  174. ;; (+ 4 ; 4 corners
  175. ;; ;; from left
  176. ;; (count-from-side trees
  177. ;; 1 0 (- rows 2) (- cols 1)
  178. ;; step-down
  179. ;; step-right
  180. ;; already-seen-table)
  181. ;; ;; from right
  182. ;; (count-from-side trees
  183. ;; 1 (- cols 1) (- rows 2) (- cols 1)
  184. ;; step-down
  185. ;; step-left
  186. ;; already-seen-table)
  187. ;; ;; from top
  188. ;; (count-from-side trees
  189. ;; 0 1 (- rows 1) (- cols 2)
  190. ;; step-right
  191. ;; step-down
  192. ;; already-seen-table)
  193. ;; ;; from bottom
  194. ;; (count-from-side trees
  195. ;; (- rows 1) 1 (- rows 1) (- cols 2)
  196. ;; step-right
  197. ;; step-up
  198. ;; already-seen-table)))))
  199. ;; (display (simple-format #f "~a\n" (array-shape trees)))
  200. ;; (display (simple-format #f "~a\n" (calc-tree-visibility trees)))
  201. ;; (pretty-print (array->list trees))