diff --git a/day18-scratch.lisp b/day18-scratch.lisp index 02b7cca..0096129 100644 --- a/day18-scratch.lisp +++ b/day18-scratch.lisp @@ -105,3 +105,58 @@ (defparameter *day-18-input-connectivity* (make-array (find-maxes *day-18-input-coords*) :initial-element 0)) +(fill-connectivity-array *day-18-input-coords* *day-18-input-connectivity*) + +(count-open-sides *day-18-input-connectivity*) + +;; now. how could i only include surface area +;; did i need to model points as what? +;; +;; well, i could start with 0th layer. there's no stone there, only air +;; and start filling with 2 +;; then count for all points as previously, but only neighbors which are 2 +;; i guess + +;; so. start at '(0 0 0) +;; then get neighbors, filter those that are 0 +;; put into queue / list - actually dfs is good enough, so just recurse? + +(point-at-is '(0 0 0) *day-18-test-graph-connectivity* 0) +(point-at-is '(0 0 0) *day-18-test-graph-connectivity* 2) + +(fill-outside-with-2 '(0 0 0) *day-18-test-graph-connectivity*) +;; this seems to work. +;; now i want to cound only outside that contacts 2? +;; so, same cound but look for neighbors 2 and count them, not 6 - stone-neighbors + +(count-open-sides-to-outside *day-18-test-graph-connectivity*) +;; well, now i need to add 1 to all sides + +(setq *day-18-test-input* + (coords-from-input "day18-test.txt")) + +(setq *day-18-test-graph-connectivity* + (make-array (find-maxes *day-18-test-input*) :initial-element 0)) +(fill-connectivity-array *day-18-test-input* *day-18-test-graph-connectivity*) + +(fill-outside-with-2 '(0 0 0) *day-18-test-graph-connectivity*) +(count-open-sides-to-outside *day-18-test-graph-connectivity*) +;; and now it's 58 +;; so, let's cound for full input? + +;;; part 2 + +(setq *day-18-input-coords* + (coords-from-input "day18-input.txt")) + +(setq *day-18-input-connectivity* + (make-array (find-maxes *day-18-input-coords*) :initial-element 0)) +(fill-connectivity-array *day-18-input-coords* *day-18-input-connectivity*) + +(fill-outside-with-2 '(0 0 0) *day-18-input-connectivity*) +(count-open-sides-to-outside *day-18-input-connectivity*) +;; there's 1 at the edge of the array. whoops. so there are 0s in the input? +;; yep. so now what, shift all by 1? and add one more +1 to the find max? +;; hahaha, this is stupid. + +;; but let's do it diff --git a/day18.lisp b/day18.lisp index e0700c7..60ee43b 100644 --- a/day18.lisp +++ b/day18.lisp @@ -11,9 +11,9 @@ (defun find-maxes (all-coords) (loop for (x y z) in all-coords - maximize (1+ x) into xs - maximize (1+ y) into ys - maximize (1+ z) into zs + maximize (+ x 2) into xs + maximize (+ y 2) into ys + maximize (+ z 2) into zs finally (return (list xs ys zs))) ) (defun fill-connectivity-array (all-coords connectivity-matrix) @@ -21,7 +21,8 @@ for (x y z) in all-coords do (setf (aref connectivity-matrix x y z) 1))) -(defun neighbors-for (coords connectivity-matrix) +;; 1 - rock, 0 - initial empty, 2 - outside air +(defun neighbors-for (coords connectivity-matrix &key (type 1)) (labels ((coords-fit (potential-point) (loop for i from 0 to 2 always (and (< (nth i potential-point) @@ -34,7 +35,7 @@ for neighbor = (mapcar #'+ coords deltas) when (and (coords-fit neighbor) - (= 1 (apply #'aref connectivity-matrix neighbor))) + (= type (apply #'aref connectivity-matrix neighbor))) collect neighbor))) (defun count-open-sides (connectivity-matrix) @@ -46,3 +47,25 @@ when (= 1 (aref connectivity-matrix x y z)) summing (- 6 (length (neighbors-for (list x y z) connectivity-matrix)))))))) + +(defun point-at-is (coords connectivity-matrix elem) + (= elem (apply #'aref connectivity-matrix coords))) + +;; call with initial coord '(0 0 0) +(defun fill-outside-with-2 (coord connectivity-matrix) + (when (point-at-is coord connectivity-matrix 0) + (setf (apply #'aref connectivity-matrix coord) 2) + (mapcar (lambda (neighbor) (fill-outside-with-2 neighbor connectivity-matrix)) + (neighbors-for coord connectivity-matrix :type 0)))) + +(defun count-open-sides-to-outside (connectivity-matrix) + (destructuring-bind (n m k) + (array-dimensions connectivity-matrix) + (loop for x from 0 below n sum + (loop for y from 0 below m sum + (loop for z from 0 below k + when (= 1 (aref connectivity-matrix x y z)) + summing (length (neighbors-for + (list x y z) + connectivity-matrix + :type 2)))))))