diff options
Diffstat (limited to '2021/11/code.tl')
-rw-r--r-- | 2021/11/code.tl | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/2021/11/code.tl b/2021/11/code.tl new file mode 100644 index 0000000..9dc724b --- /dev/null +++ b/2021/11/code.tl @@ -0,0 +1,78 @@ +(defstruct board () + w h a s + + (:postinit (bo) + (set bo.s (* bo.w bo.h))) + + (:method count-flashes (bo) + (sum bo.a (op countql #\0))) + + (:method all-flash (bo) + (eql bo.s bo.(count-flashes))) + + (:method lambda (me x y) + (if (or (minusp x) + (minusp y) + (<= me.w x) + (<= me.h y)) + #\0 + [[me.a y] x])) + + (:method lambda-set (me x y nv) + (unless (or (minusp x) + (minusp y) + (<= me.w x) + (<= me.h y)) + (set [[me.a y] x] nv)))) + +(defmacro forxy (x y bo . body) + ^(each-prod ((,y 0..(qref ,bo h)) + (,x 0..(qref ,bo w))) + ,*body)) + +(defmacro incnz (place) + (with-gensyms (p) + ^(placelet ((,p (read-once ,place))) + (if (eql #\0 ,p) #\0 (inc ,p))))) + +(defmacro mincnz (. places) + ^(progn ,*(mapcar (ret ^(incnz ,@1)) places))) + +(defun read-board-file (: (name "input")) + (flow (file-get-lines name) + vec-list + (new board + h (len @1) + w (len (first @1)) + a @1))) + +(defmeth board step (bo) + (forxy x y bo + (inc [bo x y])) + (let ((flashed t)) + (while flashed + (zap flashed) + (forxy x y bo + (when (> [bo x y] #\9) + (set flashed t + [bo x y] #\0) + (let ((x- (pred x)) (x+ (succ x)) + (y- (pred y)) (y+ (succ y))) + ;; "multi increment, from non-zero" + (mincnz [bo x- y-] [bo x y-] [bo x+ y-] + [bo x- y] [bo x+ y] + [bo x- y+] [bo x y+] [bo x+ y+])))))) + bo) + +(defun solve-part-one (: (name "input")) + (let ((bo (read-board-file name)) + (tf 0)) + (dotimes (i 100 tf) + (inc tf bo.(step).(count-flashes))))) + +(defun solve-part-two (: (name "input")) + (for ((bo (read-board-file name)) + (i 0)) + ((not bo.(all-flash)) i) + (bo.(step) + (inc i)))) |