123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- (import
- (except (rnrs base) let-values map error)
- (only (guile)
- lambda* λ
- current-output-port)
- (fileio)
- (srfi srfi-1)
- ;; let-values
- (srfi srfi-11)
- ;; hash tables
- (srfi srfi-69)
- (ice-9 pretty-print))
- (define lines (get-lines-from-file "input"))
- (define num-rows (length lines))
- (define num-cols (string-length (first lines)))
- (define trees
- (let ([trees (make-array 0 num-rows num-cols)])
- (let iter-rows ([lines° lines] [row-ind 0])
- (cond
- [(null? lines°) trees]
- [else
- (let iter-cols ([numbers-line° (first lines°)]
- [col-ind 0])
- (unless (string-null? numbers-line°)
- (array-set! trees
- (string->number (substring numbers-line° 0 1))
- row-ind
- col-ind)
- (iter-cols (substring numbers-line° 1)
- (+ col-ind 1))))
- (iter-rows (drop lines° 1)
- (+ row-ind 1))]))))
- (define step-down
- (λ (row col)
- (values (+ row 1) col)))
- (define step-left
- (λ (row col)
- (values row (- col 1))))
- (define step-up
- (λ (row col)
- (values (- row 1) col)))
- (define step-right
- (λ (row col)
- (values row (+ col 1))))
- (define array-len-in-dim
- (λ (arr dim)
- (let* ([shape (array-shape arr)]
- [dim-min-max (list-ref shape dim)])
- (+ (- (second dim-min-max)
- (first dim-min-max))
- 1))))
- (define count-visible-trees-in-direction
- (λ (trees init-row-ind init-col-ind step)
- (let ([tree-height (array-ref trees init-row-ind init-col-ind)])
- ;; already step away 1 step towards the border
- (let-values ([(next-row-ind next-col-ind) (step init-row-ind init-col-ind)])
- (let iter ([row-ind° next-row-ind] [col-ind° next-col-ind] [counter 0])
- (cond
- [(array-in-bounds? trees row-ind° col-ind°)
- (if (>= (array-ref trees row-ind° col-ind°) tree-height)
- (+ counter 1)
- (let-values ([(next-row-ind next-col-ind) (step row-ind° col-ind°)])
- (iter next-row-ind
- next-col-ind
- (+ counter 1))))]
- [else counter]))))))
- (define directional-scores
- (λ (trees row-ind col-ind)
- (list (count-visible-trees-in-direction trees row-ind col-ind step-up)
- (count-visible-trees-in-direction trees row-ind col-ind step-right)
- (count-visible-trees-in-direction trees row-ind col-ind step-down)
- (count-visible-trees-in-direction trees row-ind col-ind step-left))))
- (define score
- (λ (trees row-ind col-ind)
- (apply *
- (filter (λ (s) (not (= s 0)))
- (directional-scores trees row-ind col-ind)))))
- (define calc-tree-visibility
- (λ (trees)
- (let* ([rows (array-len-in-dim trees 0)]
- [cols (array-len-in-dim trees 1)]
- [trees-score (make-array 0 rows cols)]
- [max-row-ind (- rows 1)]
- [max-col-ind (- cols 1)])
- (let iter-rows ([row-ind° 0])
- (cond
- [(<= row-ind° max-row-ind)
- (let iter-cols ([col-ind° 0])
- (cond
- [(<= col-ind° max-col-ind)
- (array-set! trees-score
- (score trees row-ind° col-ind°)
- row-ind°
- col-ind°)
- (iter-cols (+ col-ind° 1))]
- [else
- (iter-rows (+ row-ind° 1))]))]
- [else trees-score])))))
- (simple-format
- (current-output-port)
- "~a\n"
- (apply max
- (map (λ (row) (apply max row))
- (array->list (calc-tree-visibility trees)))))
|