public
Last active

  • Download Gist
rainer-db-summary.lisp
Common Lisp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
;;; Code basically by Rainer Joswig, licensed under a cc-by-sa 2.5
;;; license; Kragen Sitaker cleaned it up a bit to get it to run.
;;; In response to my question on
;;; http://stackoverflow.com/questions/1467898/what-language-could-i-use-for
 
(require 'split-sequence)
 
(defun split-string (seq)
"Like Python's line.split()."
(split-sequence:split-sequence-if
#'(lambda (char) (cond ((eql char #\Space) t)
((eql char #\Tab) t)
((eql char #\Newline) t)
(t nil)))
seq
:remove-empty-subseqs t))
 
(defun dbscan (top-5-table stream)
"get triples from each line and put them in the hash table"
(loop for line = (read-line stream nil nil) ; no error on eof
while line
do (destructuring-bind (aa bb cc)
(split-string line) ; use your split-string
(setf bb (read-from-string bb)) ; bb -> number
(let ((current (gethash aa top-5-table))) ; check for an entry
(if current
(nconc current (list (list bb cc))) ; append
(setf current (list (list bb cc)) ; otherwise create one
(gethash aa top-5-table) current)); enter it
(when (> (length current) 5) ; more then five?
(setf (gethash aa top-5-table) ; only the five largest
(subseq (sort current #'> :key #'first) 0 5)))))))
 
(defun dbprint (table output)
"print the hashtable contents to standard output"
(maphash (lambda (aa value)
(loop for (bb cc) in value
do (format output "~a ~a ~a~%" aa bb cc)))
table))
 
(defun dbsum (input output)
"scan and sum from a stream"
(let ((top-5-table (make-hash-table :test #'equal)))
(dbscan top-5-table input)
(dbprint top-5-table output)))
 
(defun fsum (infile outfile)
"scan and sum a file"
(with-open-file (input infile :direction :input)
(with-open-file (output outfile :direction :output)
(dbsum input output))))

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.