(defstruct board () (w 0) (h 0) (a (hash)) (:method print (bo stream pretty-p) (put-line `board @{bo.w}x@{bo.h}:`) (each ((y 0..bo.h)) (each ((x 0..bo.w)) (put-char (if [bo x y] #\# #\space) stream)) (put-line))) (:method lambda (bo x y) [(or [bo.a y] nil) x]) (:method lambda-set (bo x y nv) (let ((row (or [bo.a y] (set [bo.a y] (hash))))) (set [row x] nv) (upd bo.h (max (succ y))) (upd bo.w (max (succ x))))) (:method fold-y (bo yline) (let ((a bo.a)) (del [a yline]) (set bo.h yline) (dohash (y row a bo) (when (> y yline) (let ((ry (- (* 2 yline) y))) (if [a ry] (set [a ry] [hash-uni [a ry] [a y] or]) (set [a ry] row))) (del [a y]))))) (:method fold-x (bo xline) (let ((a bo.a)) (dohash (y row a bo) (each ((x (succ xline)..bo.w)) (when [row x] (set [row (- (* 2 xline) x)] t) (del [row x]))))) (set bo.w xline)) (:method count (bo) (let ((count 0)) (dohash (y row bo.a count) (dohash (x v row) (if v (inc count))))))) (defun solve-two (: (name "input")) (let ((bo (new board))) (each ((line (file-get-lines name))) (match-case line (`@x,@y` (set [bo (toint x) (toint y)] t)) (`fold along x=@x` bo.(fold-x (toint x))) (`fold along y=@y` bo.(fold-y (toint y))))) (print bo) nil))