From b169b546a332c0e0ba783f63728c63cc80a3f650 Mon Sep 17 00:00:00 2001 From: MsK` Date: Mon, 6 Dec 2021 13:26:15 +0100 Subject: [PATCH] day 6 --- day-6/code.scm | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ day-6/input | 1 + 2 files changed, 71 insertions(+) create mode 100644 day-6/code.scm create mode 100644 day-6/input diff --git a/day-6/code.scm b/day-6/code.scm new file mode 100644 index 0000000..02d0e99 --- /dev/null +++ b/day-6/code.scm @@ -0,0 +1,70 @@ +(import (srfi :43)) ; vector extensions + +; returns a list of numbers parsed from the first line of the file, +; separated by commas +(define (read-comma-separated-numbers file) + (let loop [(draws '()) (n 0)] + (let [(c (get-char file))] + (cond + [(char=? c #\,) (loop (cons n draws) 0)] + [(char-whitespace? c) (reverse (cons n draws))] + [else (loop draws (+ (* n 10) (string->number (string c))))])))) + +;; 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 1:~% count after 256 days: ~a~%" + (simulate-growth input 256))))) diff --git a/day-6/input b/day-6/input new file mode 100644 index 0000000..ff0b23a --- /dev/null +++ b/day-6/input @@ -0,0 +1 @@ +1,1,3,5,1,3,2,1,5,3,1,4,4,4,1,1,1,3,1,4,3,1,2,2,2,4,1,1,5,5,4,3,1,1,1,1,1,1,3,4,1,2,2,5,1,3,5,1,3,2,5,2,2,4,1,1,1,4,3,3,3,1,1,1,1,3,1,3,3,4,4,1,1,5,4,2,2,5,4,5,2,5,1,4,2,1,5,5,5,4,3,1,1,4,1,1,3,1,3,4,1,1,2,4,2,1,1,2,3,1,1,1,4,1,3,5,5,5,5,1,2,2,1,3,1,2,5,1,4,4,5,5,4,1,1,3,3,1,5,1,1,4,1,3,3,2,4,2,4,1,5,5,1,2,5,1,5,4,3,1,1,1,5,4,1,1,4,1,2,3,1,3,5,1,1,1,2,4,5,5,5,4,1,4,1,4,1,1,1,1,1,5,2,1,1,1,1,2,3,1,4,5,5,2,4,1,5,1,3,1,4,1,1,1,4,2,3,2,3,1,5,2,1,1,4,2,1,1,5,1,4,1,1,5,5,4,3,5,1,4,3,4,4,5,1,1,1,2,1,1,2,1,1,3,2,4,5,3,5,1,2,2,2,5,1,2,5,3,5,1,1,4,5,2,1,4,1,5,2,1,1,2,5,4,1,3,5,3,1,1,3,1,4,4,2,2,4,3,1,1