Files
advent-of-code-2021/06-lanterfish/code.scm
2021-12-07 11:21:21 +01:00

62 lines
1.9 KiB
Scheme

(import (srfi :43)) ; vector extensions
(load "../common.scm")
;; naive version, as per the example
; simulate lanterfish growth and returns the number of fishes after given days
;(define (simulate-growth fishes days)
; (let days-loop [(day 0) (fishes fishes)]
; (if (= day days)
; (length fishes)
; (days-loop
; (+ day 1)
; (let grow [(new '()) (old fishes)]
; (if (null? old)
; new
; (if (= (car old) 0)
; (grow (cons 6 (cons 8 new)) (cdr old))
; (grow (cons (- (car old) 1) new) (cdr old)))))))))
;; optimized version
;; instead of keeping track of fishes
;; we just keep track of how many are living at each age.
;; so, the living vector is actually indexed by age
(define (sum living)
(vector-fold (lambda (i sum value) (+ sum value)) 0 living))
; returns a new vector with the new number of fishes at each age
(define (grow living)
(let [(new (make-vector 9 0))]
(vector-for-each
(lambda (age count)
(if (= age 0)
(begin
(vector-set! new 8 count)
(vector-set! new 6 count))
(vector-set! new (- age 1)
(+ count (vector-ref new (- age 1))))))
living)
new))
; simulate lanterfish growth and returns the number of fishes after given days
(define (simulate-growth fishes days)
(let [(living-per-day (make-vector 9 0))]
(let init-loop [(fishes fishes)]
(when (not (null? fishes))
(vector-set! living-per-day (car fishes)
(+ 1 (vector-ref living-per-day (car fishes))))
(init-loop (cdr fishes))))
(let loop [(day 0)
(living-per-day living-per-day)]
(if (= day days)
(sum living-per-day)
(loop (+ day 1) (grow living-per-day))))))
(call-with-input-file
"input"
(lambda (file)
(let [(input (read-comma-separated-numbers file))]
(printf "part 1:~% count after 80 days: ~a~%"
(simulate-growth input 80))
(printf "part 2:~% count after 256 days: ~a~%"
(simulate-growth input 256)))))