(load "../common.scm") (define (read-cuboid-operation file) (let* [(on/off (if (symbol=? (get-datum file) 'on) 1 0)) (x-start (begin (get-string-n file 3) (get-number file))) ; skipping " x=" (x-end (begin (get-string-n file 1) (get-number file))) ; skipping dot (y-start (begin (get-string-n file 2) (get-number file))) ; skipping "y=" (y-end (begin (get-string-n file 1) (get-number file))) ; skipping dot (z-start (begin (get-string-n file 2) (get-number file))) ; skipping "z=" (z-end (begin (get-string-n file 1) (get-number file)))] ; skipping dot (list on/off x-start x-end y-start y-end z-start z-end))) (define (load-cuboid-ops filename) (call-with-input-file filename (lambda (file) (let loop [(ops '())] (if (eof-object? (peek-char file)) (reverse ops) (loop (cons (read-cuboid-operation file) ops))))))) (define (make-3d-vector x-size y-size z-size init) (let x-loop [(x 0) (planes '())] (if (= x x-size) (reverse-list->vector planes) (x-loop (+ x 1) (cons (let y-loop [(y 0) (lines '())] (if (= y y-size) (reverse-list->vector lines) (y-loop (+ y 1) (cons (make-vector z-size init) lines)))) planes))))) ; set 3D volume to given value ; end ranges are inclusive! (define (vector-3d-set! 3d-vector value x-start x-end y-start y-end z-start z-end) (let [(width (- (vector-length (vector-ref (vector-ref 3d-vector 0) 0)) 1)) (height (- (vector-length (vector-ref 3d-vector 0)) 1)) (depth (- (vector-length 3d-vector) 1))] (let x-loop [(x (max x-start 0))] (unless (> x (min x-end width)) (let y-loop [(y (max y-start 0))] (unless (> y (min y-end height)) (let z-loop [(z (max z-start 0))] (unless (> z (min z-end depth)) (vector-set! (vector-ref (vector-ref 3d-vector x) y) z value) (z-loop (+ z 1)))) (y-loop (+ y 1)))) (x-loop (+ x 1)))))) (define (vector-3d-sum 3d-vector) (vector-fold (lambda (i a v) (+ a (vector-fold (lambda (i a v) (+ a (vector-fold (lambda (i a v) (+ a v)) 0 v))) 0 v))) 0 3d-vector)) (let [(operations (load-cuboid-ops "input")) (grid (make-3d-vector 101 101 101 0))] (let operate [(op operations)] (unless (null? op) (apply vector-3d-set! grid (cons (caar op) ; offset x/y/z ranges from -50..50 to 0..101 to fit in 3d-vector (map (lambda (x) (+ x 50)) (cdar op)))) (operate (cdr op)))) (printf "part 1:~% Cubes powered after initialization procedure: ~a~%" (vector-3d-sum grid))) ;; do step 2 using a sparse voxel octree ?