diff --git a/11-dumbo-octopus/code.scm b/11-dumbo-octopus/code.scm new file mode 100644 index 0000000..b160619 --- /dev/null +++ b/11-dumbo-octopus/code.scm @@ -0,0 +1,88 @@ +(load "../common.scm") + +; matrix visitor +; calls function with all coordinates of matrix and value at corresponding point +; value returned by function is set at the visiting coordinate +(define (visit-matrix! matrix function) + (let [(data (matrix-data matrix)) + (width-1 (- (matrix-width matrix) 1)) + (height-1 (- (matrix-height matrix) 1))] + (let y-loop [(y 0)] + (let x-loop [(x 0)] + (let [(value (vector-ref (vector-ref data y) x))] + (vector-set! (vector-ref data y) x + (function x y value)) + (when (< x width-1) + (x-loop (+ x 1))))) + (when (< y height-1) + (y-loop (+ y 1)))))) + +; increase by 1 value at x,y in given matrix +; return that value too +(define (matrix-inc! matrix x y) + (let [(v (+ 1 (matrix-get matrix x y 0)))] + (matrix-set! matrix x y v) + v)) + +(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 + (visit-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 + (visit-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)))) + diff --git a/11-dumbo-octopus/input b/11-dumbo-octopus/input new file mode 100644 index 0000000..274d3e1 --- /dev/null +++ b/11-dumbo-octopus/input @@ -0,0 +1,10 @@ +1326253315 +3427728113 +5751612542 +6543868322 +4422526221 +2234325647 +1773174887 +7281321674 +6562513118 +4824541522