;; //ideone.com/vzncKq
;; //ideone.com/B76Dki
(defstruct point x y)
(defun point+ (p q)
(make-point :x (+ (point-x p) (point-x q))
:y (+ (point-y p) (point-y q))))
(defun make-point-from-char (c)
(ecase c
(#\> (make-point :x 1 :y 0))
(#\v (make-point :x 0 :y 1))
(#\< (make-point :x -1 :y 0))
(#\^ (make-point :x 0 :y -1))))
(defun draw (chars &key start-char end-char (space-char #\*))
(loop with scr = (make-hash-table :test #'equalp)
with start = (make-point :x 0 :y 0)
for c across chars
for p = start then (point+ p (make-point-from-char c))
for end = start then p
minimize (point-x p) into min-x
minimize (point-y p) into min-y
maximize (point-x p) into max-x
maximize (point-y p) into max-y
do (setf (gethash p scr) c)
finally (when start-char (setf (gethash start scr) start-char))
(when end-char (setf (gethash end scr) end-char))
(loop for y from min-y upto max-y
do (loop for x from min-x upto max-x
for c = (gethash (make-point :x x :y y) scr)
do (princ (or c space-char)))
(terpri))))
(loop while (listen)
do (draw (read-line) :start-char #\A
:end-char #\Z
:space-char #\Space)
do (terpri))