Skip to content

Instantly share code, notes, and snippets.

@stopachka
Last active April 20, 2021 21:11
Show Gist options
  • Save stopachka/4957d20625f689a30df68c6108855e0b to your computer and use it in GitHub Desktop.
Save stopachka/4957d20625f689a30df68c6108855e0b to your computer and use it in GitHub Desktop.
(def ->tokens {"negative" 'neg "one" 1 "two" 2 "three" 3 "times" '* "plus" '+})
(defn wrap-around [tokens i]
(let [[left right] (split-at (dec i) tokens)
[l op r & right] right]
(concat left [(list op l r)] right)))
(comment
(= (wrap-around '(neg 3 * 2 + 1) 2)
'(neg (* 3 2) + 1)))
(defn wrap-right [tokens i]
(let [[left right] (split-at i tokens)
[op r & right] right]
(concat left [(list op r)] right)))
(comment
(= (wrap-right '(neg (* 3 2) + 1) 0)
'((neg (* 3 2)) + 1)))
(defn unwrap [coll]
(if (= (count coll) 1)
(first coll)
coll))
(def bedmas ['neg '* '+])
(defn top-bedmas-idx [tokens]
(->> bedmas
(map (fn [op] (.indexOf tokens op)))
(filter #(> % -1))
first))
(comment
(= (top-bedmas-idx '(neg 3 * 2 + 1)) 0))
(defn ->postfix
([tokens]
(let [idx (top-bedmas-idx tokens)
op (and idx (nth tokens idx))]
(unwrap
(cond
(not op)
tokens
(#{'* '+} op)
(->postfix (wrap-around tokens idx))
(= 'neg op)
(->postfix (wrap-right tokens idx)))))))
(comment
(= (->postfix '(neg 3 * 2 + 1))
'(+ (* (neg 3) 2) 1)))
(def neg -)
(defn nat-math [s]
(->> (string/split s #" ")
(map ->tokens)
->postfix
eval))
(comment
(= (nat-math "negative three times two plus one") -5)
(= (nat-math "one plus two times negative three") -5))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment