First, consider only horizontal and vertical lines.
$ cat 05a.rkt #lang racket (provide example-data read-input) (require (prefix-in aoc: "aoc.rkt") (prefix-in utl: "../scheme/utl.rkt")) (define (aoc05a . args) ; Return the number of deep vent points in the given sea-floor ; map. If no map is given, use the contest problem input; ; otherwise assume the argument is the string representation of ; a problem input. (deep-vent-point-count (apply read-input args))) (define (deep-vent-point-count sea-floor-map) ; Return the number of deep vent points in the given sea-floor ; map. A vent point is deep when it belongs to more than one ; vent. (define (delta c1 c2) ; Return the delta that steps from the first given value to ; the second. (utl:signum (- c2 c1))) (define plotted-points (make-hash)) (define (plot-point x y) ; Add the point with the given coordinates to the points ; plotted. (let ((pt (list x y))) (hash-set! plotted-points pt (+ (hash-ref plotted-points pt 0) 1)))) (define (plot-line ep1 ep2) ; Plot the points on the line from the first given coordinate ; to the second (inclusive at both ends). (let* ((x1 (car ep1)) (y1 (cadr ep1)) (x2 (car ep2)) (y2 (cadr ep2)) (delta-x (delta x1 x2)) (delta-y (delta y1 y2))) (when (or (zero? delta-x) (zero? delta-y)) (do ((x x1 (+ x delta-x)) (y y1 (+ y delta-y)) (n (+ (max (abs (- x2 x1)) (abs (- y2 y1))) 1) (- n 1))) ((zero? n) #t) (plot-point x y))))) (for-each (lambda (l) (plot-line (car l) (cadr l))) sea-floor-map) (foldl (lambda (c s) (+ s (if (= c 1) 0 1))) 0 (hash-values plotted-points))) (define (read-input . arg) ; Return the given sea-floor map. If no map is given, use the ; contest problem input; otherwise assume the argument is the ; string representation of a problem input. (map (lambda (l) (list (aoc:read-comma-separated-numbers (car l)) (aoc:read-comma-separated-numbers (caddr l)))) (car (aoc:aoc-read-input (if (null? arg) 5 (car arg)))))) (module+ main (aoc05a)) (aoc:define-string example-data "0,9 -> 5,9" "8,0 -> 0,8" "9,4 -> 3,4" "2,2 -> 2,1" "7,0 -> 7,4" "6,4 -> 2,0" "0,9 -> 2,9" "3,4 -> 1,4" "0,0 -> 8,8" "5,5 -> 8,2" ) (define example-result 5) (module+ test (require rackunit) (for-each (lambda (p) (check-equal? (aoc05a (car p)) (cdr p))) `(("0,0 -> 3,0" . 0) ("0,0 -> 3,0\n0,0 -> 3,0" . 4) (,example-data . ,example-result))) (check-equal? (aoc05a) 5084) ) $ raco test 05a.rkt raco test: (submod "05a.rkt" test) 4 tests passed $