data←⊃⎕NGET 'input.txt' 1 )copy dfns iotag interval←(iotag⍥⊃)(,⍤(∘.,))(iotag⍥(⊃∘⌽)) set←∪⊃,/{∪⊃,/2 interval/↓2↑⍤1⊢((⌈3÷⍨⍴s),3)⍴⊢s←⊃(//)',>-'⎕VFI ⍵}¨data ⍝ Part 1 ∇n←sim map;sand;d;dl;dr;m n←0 next: sand←500 0 loop: d←0 1+sand dl←¯1 1+sand dr←1 1+sand m←~(d dl dr)∊map :If 0<+/m sand←⊃m/(d dl dr) →((⊃⌽sand)>164)/abyss :Else map←map,⊂sand n+←1 →next :EndIf →loop abyss: ∇ ;;; lisp part2 (ql:quickload :fset) (load "data.lisp") (defparameter *map* (reduce #'fset:with `(,(fset:empty-set) ,@+data+))) (defparameter *test* (fset:set '(498 . 4) '(498 . 5) '(498 . 6) '(497 . 6) '(496 . 6) '(503 . 4) '(502 . 4) '(502 . 5) '(502 . 6) '(502 . 7) '(502 . 8) '(502 . 9) '(501 . 9) '(500 . 9) '(499 . 9) '(498 . 9) '(497 . 9) '(496 . 9) '(495 . 9) '(494 . 9))) (defun sim (map limit) (let ((n 1) (x 500) (y 0)) (loop (if (= (1+ y) limit) (progn (setq map (fset:with map (cons x y))) (incf n) (setq x 500 y 0)) (if (fset:member? (cons x (1+ y)) map) (if (fset:member? (cons (- x 1) (1+ y)) map) (if (fset:member? (cons (1+ x) (1+ y)) map) (progn (when (and (= x 500) (= y 0)) (return-from sim n)) (setq map (fset:with map (cons x y))) (incf n) (setq x 500 y 0)) (progn (incf x) (incf y))) (progn (decf x) (incf y))) (incf y))))))