75 lines
2.5 KiB
Scheme
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 ?
|