Skip to content

Instantly share code, notes, and snippets.

@jpaulorio
Last active August 21, 2016 16:04
Show Gist options
  • Save jpaulorio/40f426b7602fc195385a1b4178a18152 to your computer and use it in GitHub Desktop.
Save jpaulorio/40f426b7602fc195385a1b4178a18152 to your computer and use it in GitHub Desktop.
Two functions and a macro that implement infix notation arithmetic for simple arithmetic operations (+ - * /)
;two functions that implement infix notation arithmetic for simple arithmetic operations (+ - * /)
;my-infix-eval will reduce the given infix expression evaluating the highest precedence operation one at a time
;(my-infix-eval "(1 + 3 * 4 - 3 / 4)")
;=> 49/4
;my-infix will translate de given infix expression into clojure polish notation
;(my-infix "(1 + 3 * 4 - 3 / 4)")
;=> (- (+ 1 (* 3 4)) (/ 3 4))
;in order to evaluate the result expression, just call eval on it
;(eval(my-infix "(1 + 3 * 4 - 3 / 4)"))
;=> 49/4
;my-infix-macro will evaluate an actual clojure expression (input is not a string).
;(my-infix-macro (1 + 3 * 4 - 3 / 4))
;=> 49/4
(defn get-operations
[expression-string]
(loop [expression expression-string
result []]
(if (< (count expression) 3)
result
(recur (drop 2 expression) (conj result (take 3 expression))))))
(defn get-high-precedence
[expression]
(defn filter-highest [a b] (first (filter #(or (= (eval (second %)) a) (= (eval (second %)) b)) expression)))
(let [result (filter-highest * /)]
(if result
result
(filter-highest + -))))
(defn my-single-infix
[expression]
(if (empty? expression)
""
(list (second expression) (first expression) (last expression))))
(defn my-infix-eval
[expression-string]
(let [expression-elements (read-string expression-string)
high-precedence (get-high-precedence (get-operations expression-elements))
high-precedence-str (clojure.string/join " " high-precedence)
result-str (str (eval (my-single-infix high-precedence)))]
(if (> (count expression-elements) 1)
(recur (clojure.string/replace expression-string high-precedence-str result-str))
(first expression-elements))))
(defn my-infix
[expression-string]
(def elements-in-a-single-operation 3)
(let [expression-elements (read-string expression-string)
high-precedence (get-high-precedence (get-operations expression-elements))
high-precedence-str (clojure.string/join " " high-precedence)
result (my-single-infix high-precedence)]
(if (> (count expression-elements) elements-in-a-single-operation)
(let [temp-var (str (gensym))
temp-expression (clojure.string/replace expression-string high-precedence-str temp-var)]
(read-string (clojure.string/replace (str (my-infix temp-expression)) temp-var (str result))))
result)))
(defmacro my-infix-macro
[expression-string]
(def elements-in-a-single-operation 3)
(let [expression-elements expression-string
high-precedence (get-high-precedence (get-operations expression-elements))
high-precedence-str (clojure.string/join " " high-precedence)
result (my-single-infix high-precedence)]
(if (> (count expression-elements) elements-in-a-single-operation)
(let [temp-var (str (gensym))
temp-expression (clojure.string/replace expression-string high-precedence-str temp-var)]
(read-string (clojure.string/replace (str (my-infix temp-expression)) temp-var (str result))))
result)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment