(defparameter SP " " "U+3000 IDEOGRAPHIC SPACE")
;; (defparameter SP " ") ;半角幅のフォントで表示する場合
(defun read-pattern (stream
&key (square-char #\#)
(space-char #\.))
(loop for line = (read-line stream nil)
while (and line
(> (length line) 0))
collect (mapcar (lambda (c)
(cond ((char= c square-char)
#\#)
((char= c space-char)
#\.)
(t
(error "invalid character: ~S" c))))
(coerce line 'list))))
(let ((input-stream *standard-input*))
(loop for pattern = (read-pattern input-stream :square-char #\#
:space-char #\.)
while pattern
do (let* ((w (length (car pattern)))
(h (length pattern))
(S (make-array (list h w) :initial-contents pattern))
(L (make-array (list (- (* h 3) (- h 1))
(- (* w 3) (- w 1)))
:initial-element SP)))
(flet ((rep (y1 x1 y2 x2 c1 c2 r1 r2)
(when (and (eql (aref L y1 x1) c1)
(eql (aref L y2 x2) c2))
(or (when r1 (setf (aref L y1 x1) r1))
(when r2 (setf (aref L y2 x2) r2))))))
(loop for sy from 0 upto (1- (array-dimension S 0))
for y = (- (* sy 3) sy)
do (loop for sx from 0 upto (1- (array-dimension S 1))
for x = (- (* sx 3) sx)
do (when (eql (aref S sy sx) #\#)
(setf (aref L (+ y 0) (+ x 0)) #\┌)
(setf (aref L (+ y 0) (+ x 1)) #\┬)
(setf (aref L (+ y 0) (+ x 2)) #\┐)
(setf (aref L (+ y 1) (+ x 0)) #\├)
(setf (aref L (+ y 1) (+ x 1)) #\┼)
(setf (aref L (+ y 1) (+ x 2)) #\┤)
(setf (aref L (+ y 2) (+ x 0)) #\└)
(setf (aref L (+ y 2) (+ x 1)) #\┴)
(setf (aref L (+ y 2) (+ x 2)) #\┘))))
(loop for ly from 0 upto (1- (array-dimension L 0)) do
(loop for lx from 0 upto (1- (array-dimension L 1)) do
(when (<= (1+ lx) (1- (array-dimension L 1)))
(or (rep ly lx ly (+ lx 1) #\┐ #\┴ #\┼ #\┼)
(rep ly lx ly (+ lx 1) #\┬ #\┌ nil #\┬)
(rep ly lx ly (+ lx 1) #\┴ #\┌ nil #\┴)
(rep ly lx ly (+ lx 1) #\┴ #\└ nil #\┴)
(rep ly lx ly (+ lx 1) #\┼ #\┌ nil #\┼)
(rep ly lx ly (+ lx 1) #\┼ #\├ nil #\┼)))
(when (<= (1+ ly) (1- (array-dimension L 0)))
(or (rep ly lx (1+ ly) lx #\┼ SP #\┴ nil)
(rep ly lx (1+ ly) lx #\┼ #\┬ nil #\┼)
(rep ly lx (1+ ly) lx #\├ #\┌ nil #\├)
(rep ly lx (1+ ly) lx #\┤ #\┐ nil #\┤)
(rep ly lx (1+ ly) lx #\┴ #\├ #\┼ nil)))
(princ (aref L ly lx)))
(terpri))))
when (listen input-stream)
do (write-line "--------------------------------------------------")))