Read and Black
(defun list-to-2d-array (list) (make-array (list (length list) (length (first list))) :initial-contents list)) (defun read-map (width height) (list-to-2d-array (loop for i from 1 upto height collect (coerce (read-line) 'list)))) (defun find-start-pos (width height map) (let ((posX nil) (posY nil)) (loop for y from 0 upto (1- height) do (loop for x from 0 upto (1- width) when (char= (aref map y x) #\@) do (setf posX x posY y))) (values posX posY))) (defun reachable-tiles (x y width height map) (cond ((not (and (<= 0 x (1- width)) (<= 0 y (1- height)))) 0) ((char= #\# (aref map y x)) 0) (t (setf (aref map y x) #\#) (+ 1 (reachable-tiles (1- x) y width height map) (reachable-tiles (1+ x) y width height map) (reachable-tiles x (1+ y) width height map) (reachable-tiles x (1- y) width height map))))) (defun main () (loop for w = (read) for h = (read) until (and (zerop w ) (zerop h)) do (let ((map (read-map w h))) (multiple-value-bind (x y) (find-start-pos w h map) (format t "~A~%" (reachable-tiles x y w h map))))))
再帰で綺麗に書けるのが良いですね。しかし、mapを直接変更してるのはすこし残念です。