Files
2021-12-22 23:13:11 +01:00

75 lines
2.5 KiB
Scheme

(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 ?