aboutsummaryrefslogtreecommitdiff
path: root/racket/aoc2022/day-08/day-08.rkt
blob: 6b60eca8a78c34f1db6ff9a0cd1d3c90966026bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#lang racket

(require advent-of-code)

(struct posn (r c) #:transparent)

(define (make-tree-grid data)
  (for*/hash ([(row r) (in-indexed data)] [(col c) (in-indexed (in-string row))])
    (values (posn r c) (string->number (string col)))))

(define tree-grid (make-tree-grid (in-lines (open-aoc-input (find-session) 2022 8))))

;; part 1

(define (can-see-to-outside? p height dr dc h)
  (match-define (posn r c) p)
  (not (for/first ([n (in-naturals 1)]
                   #:do [(define p* (posn (+ r (* n dr)) (+ c (* n dc))))]
                   #:break (not (hash-has-key? h p*))
                   #:when (<= height (hash-ref h p*)))
         #true)))

(define (visible-in-any-direction? p height h)
  (for*/or ([dr (in-list '(-1 0 1))] [dc (in-list '(-1 0 1))] #:when (= 1 (abs (+ dr dc))))
    (can-see-to-outside? p height dr dc h)))

(define (count-visible-trees trees)
  (for/sum ([(tree-posn height) (in-hash trees)])
           (cond
             [(visible-in-any-direction? tree-posn height trees) 1]
             [else 0])))

(count-visible-trees tree-grid)

;; part 2

(define (scenic-score-in-direction p height dr dc h)
  (match-define (posn r c) p)
  (define score
    (for/last ([n (in-naturals 1)]
               #:do [(define p* (posn (+ r (* n dr)) (+ c (* n dc))))]
               #:break (not (hash-has-key? h p*))
               #:final (<= height (hash-ref h p*)))
      n))
  (if (not score) 0 score))

(define (scenic-score p height h)
  (for*/product ([dr (in-list '(-1 0 1))] [dc (in-list '(-1 0 1))] #:when (= 1 (abs (+ dr dc))))
                (scenic-score-in-direction p height dr dc h)))

(define (find-best-scenic-score trees)
  (apply max
         (for/list ([(tree-posn height) (in-hash trees)])
           (scenic-score tree-posn height trees))))

(find-best-scenic-score tree-grid)