Bobbi Towers / Jun 02 2019
Solving equations
Solve the equation.
0.5s
Clojure
(require [clojure.string :as str]) (defn round [n] (if (float? n) (float (/ (Math/round (* n 100)) 100)) n)) (defn parse-term [s] (if (Character/isDigit (first s)) (if (str/includes? s ".") (Float/parseFloat s) (Integer/parseInt s)) (symbol s))) (defn term1 [s op] (parse-term (str/trim (first (str/split s op))))) (defn term2 [s op] (parse-term (str/trim (last (str/split s op))))) (defn num? [s] (if-let [s (seq s)] (let [s (if (= (first s) \-) (next s) s) s (drop-while (Character/isDigit %) s) s (if (= (first s) \.) (next s) s) s (drop-while (Character/isDigit %) s)] (empty? s)))) (defn div [s] (let [left (first (str/split s "/")) right (last (str/split s "/"))] (cond (and (num? left) (num? right)) (/ (term1 s "/") (term2 s "/")) (str/includes? left "-") [(symbol (first (str/split left "\-"))) (- (/ (parse-term (last (str/split left "\-"))) (term2 s "/")))] (str/includes? right "-") [(symbol (last (str/split right "\-"))) (/ (term1 s "/") (parse-term (first (str/split right "\-"))))] (str/includes? right "+") [(/ (parse-term left) (parse-term (first (str/split right "\+")))) (symbol (last (str/split right "\+")))] (str/includes? left "+") [(symbol (first (str/split left "\+"))) (/ (parse-term (last (str/split left "\+"))) (term2 s "/"))] :else {:numer left :denom right}))) (defn parse-exp [s] (cond (str/includes? s "+") [(parse-exp (first (str/split s "\+"))) (parse-exp (last (str/split s "\+")))] (re-matches "-*(\d+\.?\d*|\d*\.?\d+)[a-zA-Z]" s) {:variable (re-find "[a-zA-Z]" s) :multiplier (parse-term (first (re-find "(-*\d+\.?\d*|\d*\.?\d+)" s)))} (str/includes? s "*") (* (term1 s "\*") (term2 s "\*")) (str/includes? s "/") (div s) (str/includes? s "-") (if (symbol? (term2 s "\-")) [(term1 s "\-") (symbol (str "-" (term2 s "\-")))] [(term1 s "\-") (if (number? (term2 s "\-")) (- (term2 s "\-")) (term2 s "\-"))]) :else (parse-term (str/trim s)))) (defn parse-eq [s] (let [left (str/trim (first (str/split s "="))) right (str/trim (last (str/split s "=")))] {:left (parse-exp left) :right (parse-exp right)})) (defn solve [s] (let [left (:left (parse-eq s)) right (:right (parse-eq s))] (cond (:numer left) (str (:numer left) " = " (round (* (parse-term (:denom left)) right))) (:numer right) (str (:numer right) " = " (round (* (parse-term (:denom right)) left))) (:multiplier left) (str (:variable left) " = " (round (/ right (:multiplier left)))) (:multiplier right) (str (:variable right) " = " (round (/ left (:multiplier right)))) (number? right) (if (number? (last left)) (str (first left) " = " (round (- right (last left)))) (if (= "-" (str (first (str (last left))))) (str (str/replace (last left) "-" "") " = " (round (- (- right (first left))))) (str (last left) " = " (round (- right (first left)))))) (number? left) (if (number? (last right)) (str (first right) " = " (round (- left (last right)))) (if (= "-" (str (first (str (last right))))) (str (str/replace (last right) "-" "") " = " (round (- (- left (first right))))) (str (last right) " = " (round (- left (first right))))))))) (solve "2/3=z/15")
"z = 10"
(defn parse-positives [s] (re-seq "\d*[a-zA-Z]|\++\d*[a-zA-Z]*" s)) (defn parse-negatives [s] (re-seq "\-[a-zA-Z\d]+[a-zA-Z]*" s)) (defn parse-variables [s] (let [term (first (re-matches "[\+-]*(\d+\.?\d*|\d*\.?\d+)*[a-zA-Z]" s))] (if (re-matches "[\+-]*(\d+\.?\d*|\d*\.?\d+)*[a-zA-Z]" s) {:variable (re-find "[a-zA-Z]+" term) :multiplier (if (re-find "[\+-]*\d+" term) (re-find "[\+-]*\d+" term) (if (re-find "-" term) -1 1))} s))) (defn parse-terms [s] (map parse-variables (into (parse-negatives s) (parse-positives s)))) (parse-terms "b+7+3b-7+5+8-5")
List(7) ("+8", "+5", Map, "+7", Map, "-7", "-5")