Subject: Re: Why is lisp better than java perl or python or ruby?
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 07 Jul 2006 04:35:23 -0500
Newsgroups: comp.lang.lisp
Message-ID: <ct-dna3qVNVGtzPZnZ2dnUVZ_rOdnZ2d@speakeasy.net>
William James <w_a_x_man@yahoo.com> wrote:
+---------------
| Lars Rune N�stdal wrote:
| > ..and yes; Common Lisp is way better that both Java, Perl,
| > Python or Ruby. Try it out, and you'll see why. :)
| 
| Really?  Then this problem should be utterly trivial for you.
| A file contains lines like
|   06-Jul.14:10 .....
|   06-Jul.09:58 .....
|   13-Jun.09:27 ..... 
| Sort them by date and time.
+---------------

Perhaps not *utterly* trivial, but it's fairly simple all the same:  ;-}

    > (defun my-parse-time (string)
	;; Some mimimal error checking
	(loop for (c i) in '((#\- 2) (#\. 6) (#\: 9) (#\space 12))
	  unless (eql c (char string i))
	    do (error "Bad punctuation in input string: ~s" string))
	;; Could use a hash table, but the list *is* quite short
	(let* ((months '("Jan" "Feb" "Mar" "Apr" "May" "Jun"
			 "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"))
	       (month (position (subseq string 3 6) months :test #'equalp))
	       (date (parse-integer string :end 2))
	       (hour (parse-integer string :start 7 :end 9))
	       (minute (parse-integer string :start 10 :end 12)))
	  (unless month
	    (error "Bad month format in input string: ~s" string))
	  ;; This result doesn't have to be the correct year, just monotonic
	  (encode-universal-time 0 minute hour date month 2006)))

    MY-PARSE-TIME
    > (let ((lines (list "06-Jul.14:10 ....."
		         "06-Jul.09:58 ....."
		         "13-Jun.09:27 .....")))
        (format t "~{~s~%~}" (sort lines #'< :key 'my-parse-time))
	(values))			; [suppress printing the value]
    "13-Jun.09:27 ....."
    "06-Jul.09:58 ....."
    "06-Jul.14:10 ....."
    > 

And if you insist on the lines really  being in a file first, and
being printed without the quotes around them, then:

    > (with-open-file (s "foo.txt")
	(let ((lines (loop for line = (read-line s nil nil)
			   while line
		       collect line)))
          (format t "~{~a~%~}" (sort lines #'< :key 'my-parse-time))
	  (values)))
    13-Jun.09:27 .....  
    06-Jul.09:58 .....
    06-Jul.14:10 .....
    > 

If you want the result to go into another file, we can do that too:

    > (with-open-file (in "foo.txt")
	(with-open-file (out "foo.out" :direction :output
				       :if-exists :supersede)
	  (let ((lines (loop for line = (read-line in nil nil)
			     while line
			 collect line)))
	    (format out "~{~a~%~}" (sort lines #'< :key 'my-parse-time)))))

    NIL
    > (quit)
    $ cat foo.out
    13-Jun.09:27 .....  
    06-Jul.09:58 .....
    06-Jul.14:10 .....
    $ 


-Rob

p.s. Note: The values-suppression trick is non-standard, but works
in a number of CL implementations [CMUCL & CLISP, for two].

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607