Programming challenge

Derek Davis derek.davis at gmail.com
Fri Sep 28 12:17:41 MDT 2007


I feel the need to precede my Lisp solution with several disclaimers,
#2 being one of the most important - I am only barely learning Lisp.
Go easy on me. :)

Disclaimers:
   1) This does not do order of operations.  It's ugly enough as it is
   2) I am very recently learning Lisp.  I don't know it well, so this is ugly
   3) I misspelled variable names
   4) This took longer to write than it should.  See disclaimer 2.
   5) The process-time function (IMHO) is pretty sweet
   6) parse-string is hideous
   7) split-by-space and split-by-colon are
       a) not mine
       b) repeating themselves, should be a generic function.  ah well.
   8) op1 and rater in parse-string shouldn't also be keeping state,
by holding invalid values till they get the real ones.  They do
anyway.

Anyway, a lisp solution.
Usage -> (parse-string "2:3:20.2 + 5:2")

Derek

(defun parse-string (str)
  (let ((op1 -1) (rater "_"))
    (progn
      (dolist (elt (split-by-space str))
	(if (= -1 op1)
	    (setf op1 (process-time elt))
	    (if (string-equal "_" rater)
		(setf rater elt)
	        (progn
		  (setf op1
		      (mathefy rater op1 (process-time elt)))
		  (setf rater "_")))))
      op1)))

(defun process-time (str)
  (let ((place (length (split-by-colon str))))
    (loop for x in (split-by-colon str)
	  summing (progn (setf place (1- place))
			 (* (expt 60 place) (read-from-string x))))))

(defun mathefy (rater op1 op2)
  (cond
   ((equal rater "+")
    (+ op1 op2))
   ((equal rater "-")
    (- op1 op2))
   ((equal rater "/")
    (/ op1 op2))
   ((equal rater "*")
    (* op1 op2))
   (* (+ op1 op2))))

(defun split-by-space (str)
  (loop for i = 0 then (1+ j)
	as j = (position #\Space str :start i)
	collect (subseq str i j)
	while j))

(defun split-by-colon (str)
  (loop for i = 0 then (1+ j)
	as j = (position #\Colon str :start i)
	collect (subseq str i j)
	while j))



More information about the PLUG mailing list