AoC '21, Day 17, second problem, rvc


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 
  
 $