aboutsummaryrefslogtreecommitdiff
path: root/2021/day-17/day-17.rkt
blob: b8563a55f9649efa24bcbae5c8bf708de9bd0800 (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
#lang racket
(require "../../jj-aoc.rkt"
         threading)

(define-values (x-min x-max y-min y-max)
  (~> (open-day 17 2021)
    port->string
    (regexp-match #px"target area: x=(.*)\\.\\.(.*), y=(.*)\\.\\.(.*)\n" _)
    rest
    (map string->number _)
    (apply values _)))

(define (hit? x y)
  (and (x . >= . x-min)
       (x . <= . x-max)
       (y . >= . y-min)
       (y . <= . y-max)))

(define (miss? x y)
  (or (y . < . y-min)
      (x . > . x-max)))

(define (drag dx i) (max (- dx i) 0))
(define (gravity dy i) (- dy i))

(define (find-trajectory-apex dx dy)
  (for/fold ([x 0] [y 0] [y-apex 0] [result #f]
                   #:result (list y-apex result))
            ([i (in-naturals)]
             #:break result)
    (cond
      [(hit? x y) (values dx dy y-apex 'hit)]
      [(miss? x y) (values x y 'miss 'miss)]
      [else
       (values (+ x (drag dx i))
               (+ y (gravity dy i))
               (if (y . > . y-apex) y y-apex)
               #f)])))

(define on-target
  (for*/list ([dx (in-inclusive-range 1 x-max)]
              [dy (in-inclusive-range y-min (abs (* 2 y-max)))]
              [velocity (in-value (find-trajectory-apex dx dy))]
              #:when (equal? (second velocity) 'hit))
    (list dx dy (first velocity))))

;; part 1
(~>> on-target
     (argmax third)
     third)

;; part 2
(length on-target)