Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
53
Task/Arithmetic-evaluation/Clojure/arithmetic-evaluation.clj
Normal file
53
Task/Arithmetic-evaluation/Clojure/arithmetic-evaluation.clj
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
(def precedence '{* 0, / 0
|
||||
+ 1, - 1})
|
||||
|
||||
(defn order-ops
|
||||
"((A x B) y C) or (A x (B y C)) depending on precedence of x and y"
|
||||
[[A x B y C & more]]
|
||||
(let [ret (if (<= (precedence x)
|
||||
(precedence y))
|
||||
(list (list A x B) y C)
|
||||
(list A x (list B y C)))]
|
||||
(if more
|
||||
(recur (concat ret more))
|
||||
ret)))
|
||||
|
||||
(defn add-parens
|
||||
"Tree walk to add parens. All lists are length 3 afterwards."
|
||||
[s]
|
||||
(clojure.walk/postwalk
|
||||
#(if (seq? %)
|
||||
(let [c (count %)]
|
||||
(cond (even? c) (throw (Exception. "Must be an odd number of forms"))
|
||||
(= c 1) (first %)
|
||||
(= c 3) %
|
||||
(>= c 5) (order-ops %)))
|
||||
%)
|
||||
s))
|
||||
|
||||
(defn make-ast
|
||||
"Parse a string into a list of numbers, ops, and lists"
|
||||
[s]
|
||||
(-> (format "'(%s)" s)
|
||||
(.replaceAll , "([*+-/])" " $1 ")
|
||||
load-string
|
||||
add-parens))
|
||||
|
||||
(def ops {'* *
|
||||
'+ +
|
||||
'- -
|
||||
'/ /})
|
||||
|
||||
(def eval-ast
|
||||
(partial clojure.walk/postwalk
|
||||
#(if (seq? %)
|
||||
(let [[a o b] %]
|
||||
((ops o) a b))
|
||||
%)))
|
||||
|
||||
(defn evaluate [s]
|
||||
"Parse and evaluate an infix arithmetic expression"
|
||||
(eval-ast (make-ast s)))
|
||||
|
||||
user> (evaluate "1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1")
|
||||
60
|
||||
Loading…
Add table
Add a link
Reference in a new issue