AoC'21, day 6, first problem rvc


Given a fish population at day 0, what is the population at day 80?

 $ cat 06a.rkt  
 #lang racket 
  
  
 (provide 
  example-data 
  lanternfish-population-growth 
  ) 
  
  
 (require 
   (prefix-in aoc: "aoc.rkt") 
   ) 
  
  
 (define (aoc06a . args) 
  
   ; Return the population of the given lanternfish population 
   ; after it's been aged by 80 days.  If no population is given, 
   ; use the contest problem input; otherwise assume the argument 
   ; is the string representation of a problem input. 
  
   (lanternfish-population-growth 80 
     (apply aoc:read-comma-separated-numbers (cons 6 args)))) 
  
  
 (define (lanternfish-population-growth days population) 
  
   ; Return the population of the given lanternfish population 
   ; after it's been aged by the give number of days. 
  
   (let* 
  
     ((census (make-vector 7 0)) 
      (zero-offset 0) 
      (census-index (lambda (i) (remainder (+ i zero-offset) 7))) 
      (census-ref 
        (lambda (i) (vector-ref census (census-index i)))) 
      (census-set! 
        (lambda (i v) (vector-set! census (census-index i) v))) 
      (advance-zero-offset 
        (lambda () (set! zero-offset (census-index 1)))) 
  
      (brood (make-vector 2 0)) 
      (brood-ref (lambda (i) (vector-ref brood i))) 
      (brood-set! (lambda (i v) (vector-set! brood i v))) 
  
      (vsum 
        (lambda (v) (foldl (lambda (x s) (+ x s)) 0 (vector->list v)))) 
      ) 
  
     (for-each  
       (lambda (f) (vector-set! census f (+ 1 (vector-ref census f)))) 
       population) 
  
     (do ((d 0 (+ d 1))) ((= d days) #t) 
       (let ((day-7 (brood-ref 0))) 
         (brood-set! 0 (brood-ref 1)) 
         (brood-set! 1 (census-ref 0)) 
         (advance-zero-offset) 
         (census-set! 6 (+ (census-ref 6) day-7)))) 
  
     (+ (vsum census) (vsum brood)))) 
  
  
 (module+ main 
   (aoc06a) 
   ) 
  
  
 (define example-data "3,4,3,1,2") 
 (define example-18-day-result 26) 
 (define example-80-day-result 5934) 
  
  
 (module+ test 
  
   (require rackunit) 
  
   (define population 
     (aoc:read-comma-separated-numbers 6 example-data)) 
  
   (for-each 
     (lambda (p) 
       (check-equal? 
         (lanternfish-population-growth (car p) population) 
         (cdr p))) 
     '((0 . 5)    
       (1 . 5)    (10 . 12)   
       (2 . 6)    (11 . 15)   
       (3 . 7)    (12 . 17)   
       (4 . 9)    (13 . 19)   
       (5 . 10)   (14 . 20)   
       (6 . 10)   (15 . 20)   
       (7 . 10)   (16 . 21)   
       (8 . 10)   (17 . 22)   
       (9 . 11)   (18 . 26))) 
  
   (check-equal? 
     (lanternfish-population-growth 80 population) 
     example-80-day-result) 
  
   (check-equal? (aoc06a) 380243) 
   ) 
  
 $ raco test 06a.rkt  
 raco test: (submod "06a.rkt" test) 
 21 tests passed 
  
 $