RosettaCodeData/Task/Text-processing-1/Common-Lisp/text-processing-1.lisp

49 lines
1.8 KiB
Common Lisp

(defvar *invalid-count*)
(defvar *max-invalid*)
(defvar *max-invalid-date*)
(defvar *total-sum*)
(defvar *total-valid*)
(defun read-flag (stream date)
(let ((flag (read stream)))
(if (plusp flag)
(setf *invalid-count* 0)
(when (< *max-invalid* (incf *invalid-count*))
(setf *max-invalid* *invalid-count*)
(setf *max-invalid-date* date)))
flag))
(defun parse-line (line)
(with-input-from-string (s line)
(let ((date (make-string 10)))
(read-sequence date s)
(cons date (loop repeat 24 collect (list (read s)
(read-flag s date)))))))
(defun analyze-line (line)
(destructuring-bind (date &rest rest) line
(let* ((valid (remove-if-not #'plusp rest :key #'second))
(n (length valid))
(sum (apply #'+ (mapcar #'rationalize (mapcar #'first valid))))
(avg (if valid (/ sum n) 0)))
(incf *total-valid* n)
(incf *total-sum* sum)
(format t "Line: ~a Reject: ~2d Accept: ~2d ~
Line_tot: ~8,3f Line_avg: ~7,3f~%"
date (- 24 n) n sum avg))))
(defun process (pathname)
(let ((*invalid-count* 0) (*max-invalid* 0) *max-invalid-date*
(*total-sum* 0) (*total-valid* 0))
(with-open-file (f pathname)
(loop for line = (read-line f nil nil)
while line
do (analyze-line (parse-line line))))
(format t "~%File = ~a" pathname)
(format t "~&Total = ~f" *total-sum*)
(format t "~&Readings = ~a" *total-valid*)
(format t "~&Average = ~10,3f~%" (/ *total-sum* *total-valid*))
(format t "~%Maximum run(s) of ~a consecutive false readings ends at ~
line starting with date(s): ~a~%"
*max-invalid* *max-invalid-date*)))