123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- (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 visible-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])
- (cond
- [(array-in-bounds? trees row-ind° col-ind°)
- (if (>= (array-ref trees row-ind° col-ind°) tree-height)
- #f
- (let-values ([(next-row-ind next-col-ind) (step row-ind° col-ind°)])
- (iter next-row-ind next-col-ind)))]
- [else #t]))))))
- (define visible?
- (λ (trees row-ind col-ind)
- ;; idea: calculate number of directions in which tree is visible
- (or (visible-in-direction? trees row-ind col-ind step-up)
- (visible-in-direction? trees row-ind col-ind step-right)
- (visible-in-direction? trees row-ind col-ind step-down)
- (visible-in-direction? trees row-ind col-ind step-left))))
- (define calc-tree-visibility
- (λ (trees)
- (let* ([rows (array-len-in-dim trees 0)]
- [cols (array-len-in-dim trees 1)]
- [visibility (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
- ;; go to next row
- [(<= col-ind° max-col-ind)
- (cond
- [(visible? trees row-ind° col-ind°)
- (simple-format (current-output-port) "r:~a,c:~a is visibile\n" row-ind° col-ind°)
- (array-set! visibility 1 row-ind° col-ind°)
- (iter-cols (+ col-ind° 1))]
- [else
- (iter-cols (+ col-ind° 1))])]
- [else
- (iter-rows (+ row-ind° 1))]))]
- [else visibility])))))
- (simple-format (current-output-port)
- "~a\n"
- (apply
- +
- (map (λ (row) (apply + row))
- (array->list (calc-tree-visibility trees)))))
- ;; (define count-in-direction
- ;; (λ (trees start-row-ind start-col-ind next already-seen-table)
- ;; (let ([rows (array-len-in-dim trees 0)]
- ;; [cols (array-len-in-dim trees 1)])
- ;; (let iter ([row-ind start-row-ind]
- ;; [col-ind start-col-ind]
- ;; [max-tree-height° -1]
- ;; [counter 0])
- ;; (cond
- ;; [(>= col-ind cols) counter]
- ;; [(< col-ind 0) counter]
- ;; [(>= row-ind rows) counter]
- ;; [(< row-ind 0) counter]
- ;; [else
- ;; (let ([current-tree-height (array-ref trees row-ind col-ind)])
- ;; (cond
- ;; [(> current-tree-height max-tree-height°)
- ;; (let-values ([(next-row-ind next-col-ind) (next row-ind col-ind)])
- ;; (hash-table-ref table key [default-thunk])
- ;; ;; (cond
- ;; ;; [(hash-table-ref/default already-seen-table (cons row-ind col-ind) #f)
- ;; ;; (iter next-row-ind
- ;; ;; next-col-ind
- ;; ;; current-tree-height
- ;; ;; (+ counter 1))
- ;; ;; ]
- ;; ;; [else ...])
- ;; )]
- ;; [else
- ;; (let-values ([(next-row-ind next-col-ind) (next row-ind col-ind)])
- ;; (iter next-row-ind
- ;; next-col-ind
- ;; max-tree-height°
- ;; counter))]))])))))
- ;; (define count-from-side
- ;; (λ (trees
- ;; start-row-ind start-col-ind
- ;; max-row-ind max-col-ind
- ;; next-line
- ;; next-tree
- ;; already-seen-table)
- ;; (let ([rows (array-len-in-dim trees 0)]
- ;; [cols (array-len-in-dim trees 0)])
- ;; (let iter ([row-ind start-row-ind]
- ;; [col-ind start-col-ind]
- ;; [counter 0])
- ;; (cond
- ;; ;; in bounds check
- ;; [(and (<= row-ind max-row-ind)
- ;; (>= row-ind 0)
- ;; (<= col-ind max-col-ind)
- ;; (>= col-ind 0))
- ;; (simple-format (current-output-port) "starting at: r=~a,c=~a\n" row-ind col-ind)
- ;; ;; Calculate the starting point of the next line to count
- ;; ;; visible trees in.
- ;; (let-values ([(next-row-ind next-col-ind) (next-line row-ind col-ind)])
- ;; (iter next-row-ind
- ;; next-col-ind
- ;; (+ counter
- ;; (count-in-direction trees
- ;; row-ind
- ;; col-ind
- ;; next-tree
- ;; already-seen-table))))]
- ;; [else counter])))))
- ;; (define count-trees
- ;; (λ (trees)
- ;; (let ([rows (array-len-in-dim trees 0)]
- ;; [cols (array-len-in-dim trees 0)]
- ;; [already-seen-table (make-hash-table equal?)])
- ;; (simple-format (current-output-port) "rows: ~a\n" rows)
- ;; (simple-format (current-output-port) "cols: ~a\n" cols)
- ;; (+ 4 ; 4 corners
- ;; ;; from left
- ;; (count-from-side trees
- ;; 1 0 (- rows 2) (- cols 1)
- ;; step-down
- ;; step-right
- ;; already-seen-table)
- ;; ;; from right
- ;; (count-from-side trees
- ;; 1 (- cols 1) (- rows 2) (- cols 1)
- ;; step-down
- ;; step-left
- ;; already-seen-table)
- ;; ;; from top
- ;; (count-from-side trees
- ;; 0 1 (- rows 1) (- cols 2)
- ;; step-right
- ;; step-down
- ;; already-seen-table)
- ;; ;; from bottom
- ;; (count-from-side trees
- ;; (- rows 1) 1 (- rows 1) (- cols 2)
- ;; step-right
- ;; step-up
- ;; already-seen-table)))))
- ;; (display (simple-format #f "~a\n" (array-shape trees)))
- ;; (display (simple-format #f "~a\n" (calc-tree-visibility trees)))
- ;; (pretty-print (array->list trees))
|