Determine how many trajectories hit the target.
$ cat 17b.rkt #lang racket (require (prefix-in aoc: "aoc.rkt")) (define (aoc17b . input) ; Return the number torpedo trajectories that hit the given target. If no ; target is given, use the contest problem input; otherwise assume the ; argument is the string representation of a problem input. (trajectory-counts (apply read-input input))) (define (read-input . input) ; Return the target coordinates. If no target is ; given, use the contest problem input; otherwise ; assume the argument is the string representation ; of a problem input. (map string->number (flatten (map (lambda (s) (string-split s #px"[xy=.,]+")) (cddr (flatten (aoc:aoc-read-input (if (null? input) 17 (car input))))))))) (define (trajectory-counts target) ; Return the number of trajectories that hit the given target. (define x-min (car target)) (define x-max (cadr target)) (define y-min (caddr target)) (define y-max (cadddr target)) (define (intersecting-trajectory x-velocity y-velocity) ; Return #t iff a torpedo with the given initial velocity ; hits the target. (let loop ((x 0) (y 0) (x-velocity x-velocity) (y-velocity y-velocity)) (cond ((or (> x x-max) (< y y-min)) #f) ((and (<= x-min x) (<= y y-max)) #t) (#t (loop (+ x x-velocity) (+ y y-velocity) (max 0 (- x-velocity 1)) (- y-velocity 1)))))) (let x-loop ((x 0) (hit-count 0)) (if (> x x-max) hit-count (let y-loop ((y (abs y-min)) (hit-count hit-count)) (if (< y y-min) (x-loop (+ x 1) hit-count) (y-loop (- y 1) (+ hit-count (if (intersecting-trajectory x y) 1 0)))))))) (module+ main (aoc17b)) (aoc:define-string example-data "target area: x=20..30, y=-10..-5") (define example-result 112) (module+ test (require rackunit) (check-equal? (aoc17b example-data) example-result) (check-equal? (aoc17b) 2994) ) $ raco test 17b.rkt raco test: (submod "17b.rkt" test) 2 tests passed $