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))
/*
PLUG: http://plug.org, #utah on irc.freenode.net
Unsubscribe: http://plug.org/mailman/options/plug
Don't fear the penguin.
*/