[quiz] (Partial?) solution to the second quiz
Pablo Barenbaum
foones at gmail.com
Mon May 8 21:38:38 UTC 2006
I post a partial solution to the off-side-reader quiz.
I say "partial" because, even though it reads in off-side mode,
I'm not sure if it works as it is supposed in every case, i.e.:
- what about blank lines?
- what about comments?
- the !# is supposed to be alone in a single line?
- ...
I'm afraid I tend overuse format and loop.
It is also possibly very inefficient: it generates a new string
with the "correct", inherent, parens made explicit, then reads it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defpackage :quiz2)
(in-package :quiz2)
(defvar *blanks* '(#\Space #\Tab #\Newline #\Return))
(defun distance (str prev-dist)
(if (zerop (length (string-left-trim *blanks* str)))
prev-dist
(do ((col 0 (1+ col)))
((not (member (aref str col) *blanks* :test #'char=)) col))))
(defun read-off-side-to-string (stream)
(let ((prev-line "")
(prev-dists '())
(prev-dist 0))
(with-output-to-string (s)
(format s "(progn ")
(loop
for line = (read-line stream nil 'eof)
while (not (or (eq line 'eof)
(string= line "!#")))
do (let ((dist (distance line prev-dist)))
(when (> dist prev-dist)
(push dist prev-dists)
(format s "("))
(format s "~A~%" prev-line)
(loop while (and (not (null prev-dists))
(< dist (car prev-dists)))
do (pop prev-dists)
do (format s ")"))
(setf prev-line line)
(setf prev-dist dist)))
(format s "~A~%" prev-line)
(loop while (not (null prev-dists))
do (pop prev-dists)
do (format s ")"))
(format s ")~%"))))
(defun read-off-side (stream c n)
(nth-value 0 (read-from-string (read-off-side-to-string stream))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
More information about the Quiz
mailing list