73 lines
1.8 KiB
Scheme
73 lines
1.8 KiB
Scheme
(load "../common.scm")
|
|
|
|
(define-record-type vec2i (fields x y))
|
|
|
|
; flash given octopus
|
|
; ie. increase energy of neighbor ones
|
|
; returns list of octopuses that now need to flash too
|
|
(define (flash! matrix x y)
|
|
(let [(extra '())]
|
|
(let y-loop [(yy (- y 1))]
|
|
(let x-loop [(xx (- x 1))]
|
|
(when (not (and (= xx x) (= yy y)))
|
|
(when (< (matrix-get matrix xx yy 0) 10)
|
|
(when (= (matrix-inc! matrix xx yy) 10)
|
|
(set! extra (cons (make-vec2i xx yy) extra)))))
|
|
(when (< xx (+ x 1))
|
|
(x-loop (+ xx 1))))
|
|
(when (< yy (+ y 1))
|
|
(y-loop (+ yy 1))))
|
|
extra))
|
|
|
|
(define (step! matrix)
|
|
(let [(flashes '())]
|
|
; increase energy of all octopuses
|
|
(update-matrix!
|
|
matrix
|
|
(lambda (x y energy)
|
|
(when (= energy 9)
|
|
(set! flashes (cons (make-vec2i x y) flashes)))
|
|
(+ 1 energy)))
|
|
; recursively flash octopuses
|
|
(let loop [(flash flashes)]
|
|
(when (not (null? flash))
|
|
(loop (append (cdr flash)
|
|
(flash! matrix (vec2i-x (car flash))
|
|
(vec2i-y (car flash)))))))
|
|
; drain all octopuses that flashed
|
|
(update-matrix!
|
|
matrix
|
|
(lambda (x y energy)
|
|
(if (< energy 10) energy 0)))
|
|
; count octopuses that flashed
|
|
(vector-fold
|
|
(lambda (y sum line)
|
|
(+ sum
|
|
(vector-fold
|
|
(lambda (x sum value)
|
|
(if (= value 0) (+ sum 1) sum))
|
|
0 line)))
|
|
0 (matrix-data matrix))))
|
|
|
|
(call-with-input-file
|
|
"input"
|
|
(lambda (file)
|
|
(let [(matrix (load-matrix file))
|
|
(flash-count 0)]
|
|
(let loop [(i 0)]
|
|
(set! flash-count (+ flash-count
|
|
(step! matrix)))
|
|
(when (< i 99)
|
|
(loop (+ i 1))))
|
|
(printf "part 1:~% ~a flashes after a hundred steps.~%"
|
|
flash-count)
|
|
(let loop [(i 100)]
|
|
(if (= (matrix-sum matrix) 0)
|
|
(printf "part 2:~% Octopuses synchronized at step ~a.~%" i)
|
|
(begin
|
|
(step! matrix)
|
|
(loop (+ i 1))))))))
|
|
|
|
|
|
|