aboutsummaryrefslogtreecommitdiff
path: root/aoc2022/day-15/day-15.rkt
blob: b050807b57e842a44af50f80fa537e1c2e14df2d (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
#lang racket

(require advent-of-code
         threading
         fancy-app
         algorithms
         (prefix-in iset- data/integer-set))

(struct beacon-record (sensor beacon))
(struct posn (x y))

(define beacon-records
  (~> (fetch-aoc-input (find-session) 2022 15 #:cache #true)
      (string-split "\n")
      (map (λ~> (string-replace #px"[^\\d\\s-]" "")
                string-split
                (map string->number _)
                (chunks-of 2)
                (map (apply posn _) _)
                (apply beacon-record _))
           _)))

(define (manhattan-distance-to-beacon record)
  (match-define (beacon-record (posn sx sy) (posn bx by)) record)
  (+ (abs (- sx bx)) (abs (- sy by))))

(define (coverage-at-row record row)
  (match-define (beacon-record (posn sx sy) _) record)
  (define x-distance (- (manhattan-distance-to-beacon record) (abs (- row sy))))
  (cond
    [(negative? x-distance) (iset-make-range)]
    [else (iset-make-range (- sx x-distance) (+ sx x-distance))]))

(define (total-coverage-at-row records row)
  (for/fold ([coverage (iset-make-range)]) ([r (in-list records)])
    (iset-union coverage (coverage-at-row r row))))

;; part 1
(define (coverage-without-beacons records row)
  (~> (total-coverage-at-row records row)
      iset-count
      (- (count (λ (b) (= row (posn-y b)))
                (~> beacon-records (map beacon-record-beacon _) remove-duplicates)))))

(coverage-without-beacons beacon-records 2000000)

;; part 2
(define (find-only-beacon beacon-records size)
  (for/first ([y (in-range 0 size)]
              #:do [(define xs (iset-complement (total-coverage-at-row beacon-records y) 0 size))]
              #:when (= 1 (iset-count xs)))
    (+ (* 4000000 (iset-get-integer xs)) y)))

(find-only-beacon beacon-records 4000000)