Skip to content

Instantly share code, notes, and snippets.

@mcsf
Created September 20, 2012 20:23
Show Gist options
  • Save mcsf/1c13f6bbdceb32cf703b to your computer and use it in GitHub Desktop.
Save mcsf/1c13f6bbdceb32cf703b to your computer and use it in GitHub Desktop.
text-count.lisp
;; Constants
(defconstant *whitespace* '(#\space #\tab #\newline #\return))
(defconstant *separator* "EOF")
;; Predicates
(defun whitespace-p (char)
"Returns a given character if it is whitespace, NIL otherwise."
(find char *whitespace*))
(defun empty-line-p (line)
"Returns T if a given line (string) is made up entirely of whitespace, NIL
otherwise."
(string= "" (remove-if #'whitespace-p line)))
;; Processing functions
(defun process-line (line)
"Returns word count for a given line (string)."
(unless (string= line *separator*)
(if (empty-line-p line)
0
(1+ (count-if #'whitespace-p line)))))
(defun process-file (file)
(with-open-file (in file)
(do* ((line "" (read-line in nil))
(count-list '(0)
(let ((line-count (process-line line)))
(if line-count
(cons (+ (car count-list) line-count) (cdr count-list))
(cons 0 count-list)))))
((not line) count-list))))
;; Wrappers
(defun word-count (file)
(reverse (process-file file)))
(defun word-count-verbose (file)
(let ((wch (process-file file)))
(if (cdr wch)
(let* ((wc1 (second wch))
(wc2 (first wch))
(wct (+ wc1 wc2)))
(format t "~d/~d (~,1f%) words (~d remaining).~%"
wc1 wct (float (* 100 (/ wc1 wct))) wc2))
(format t "~a words.~%" (first wch)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment