Last active
August 21, 2016 16:04
-
-
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 (+ - * /)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;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