Given an array of numbers, each number in [0..9], find the local minima and return the sum of the minima plus the number of minima found. A local minima is a number i that is smaller than all its neighbors, where a neighbor is the number immediately to the left, right, above or below i.
$ cat 09a.rkt #lang racket (provide example-input read-input ) (require (prefix-in aoc: "aoc.rkt") (prefix-in array: "array.rkt") ) (define (aoc09a . args) ; Return the sum of the low-point risk levels in the given ; seabed map. If no map is given, use the contest problem ; input; otherwise assume the argument is the string ; representation of a problem input. (low-points-risk-sum (apply read-input args))) (define (low-points-risk-sum map) ; Return the sum of the low-point risks in the given map. (define (low-point? v n) ; Return #t iff the given value is less than all the given ; neighboring values. (foldl (lambda (n b) (and b (< v n))) #t n)) (let ((risk-sum 0)) (array:plus-neighbors map (lambda (x y v neighbors) (when (low-point? v neighbors) (set! risk-sum (+ risk-sum v 1))))) risk-sum)) (define (read-input . arg) ; Return the seabed map described by the problem input. If no ; argument is given, use the contest problem input; otherwise ; assume the argument is the string representation of a problem ; input. (array:new (map aoc:digit-string->digit-list (flatten (car (aoc:aoc-read-input (if (null? arg) 9 (car arg)))))))) (define example-input (aoc:strings->string "2199943210" "3987894921" "9856789892" "8767896789" "9899965678" )) (define example-output 15) (module+ main (aoc09a) ) (module+ test (require rackunit) (for-each (lambda (p) (check-equal? (low-points-risk-sum (read-input (car p))) (cdr p))) `(("111\n101\n111" . 1) ("010\n222\n030" . 4) (,example-input . ,example-output))) (check-equal? (aoc09a) 532) ) $ raco test 09a.rkt raco test: (submod "09a.rkt" test) 4 tests passed $