Skip to content

Instantly share code, notes, and snippets.

@Ivana-
Created July 31, 2024 22:43
Show Gist options
  • Save Ivana-/85b1e1bfc56c5382b05ca809bb1addba to your computer and use it in GitHub Desktop.
Save Ivana-/85b1e1bfc56c5382b05ca809bb1addba to your computer and use it in GitHub Desktop.
Simple equation solver
sandbox=>
equation 1 : (x + 50) * 10 - 15 = 10
(((x + 50) * 10) - 15) = 10
((x + 50) * 10) = (10 + 15)
(x + 50) = ((10 + 15) / 10)
x = (((10 + 15) / 10) - 50)
solution: x = (((10 + 15) / 10) - 50) = -95/2
equation 2 : ((x + 10) + 30) = 10 + 20
((x + 10) + 30) = (10 + 20)
(x + 10) = ((10 + 20) - 30)
x = (((10 + 20) - 30) - 10)
solution: x = (((10 + 20) - 30) - 10) = -10
equation 3 : ((x + 10) + (20 + 30)) = 10 + 20
((x + 10) + (20 + 30)) = (10 + 20)
(x + 10) = ((10 + 20) - (20 + 30))
x = (((10 + 20) - (20 + 30)) - 10)
solution: x = (((10 + 20) - (20 + 30)) - 10) = -30
equation 4 : ((20 + 30) + (x + 10)) = 10 + 20
((20 + 30) + (x + 10)) = (10 + 20)
(x + 10) = ((10 + 20) - (20 + 30))
x = (((10 + 20) - (20 + 30)) - 10)
solution: x = (((10 + 20) - (20 + 30)) - 10) = -30
equation 5 : (((3 * x) * 4) * 5) = 1
(((3 * x) * 4) * 5) = 1
((3 * x) * 4) = (1 / 5)
(3 * x) = ((1 / 5) / 4)
x = (((1 / 5) / 4) / 3)
solution: x = (((1 / 5) / 4) / 3) = 1/60
equation 6 : (((3 / x) * 4) * 5) = 1
(((3 / x) * 4) * 5) = 1
((3 / x) * 4) = (1 / 5)
(3 / x) = ((1 / 5) / 4)
x = (3 / ((1 / 5) / 4))
solution: x = (3 / ((1 / 5) / 4)) = 60N
equation 7 : (((3 / (x + 10)) * 4) * 5) = 1
(((3 / (x + 10)) * 4) * 5) = 1
((3 / (x + 10)) * 4) = (1 / 5)
(3 / (x + 10)) = ((1 / 5) / 4)
(x + 10) = (3 / ((1 / 5) / 4))
x = ((3 / ((1 / 5) / 4)) - 10)
solution: x = ((3 / ((1 / 5) / 4)) - 10) = 50N
(ns sandbox
(:require
[clojure.string :as str]))
;; // Write a simple equation parser and solver. The equation can have a single variable x, operations +, -, *, /, integer numbers, and parenthesis.
;; // It’s guaranteed that there’s only one occurrence of x .
;; // The solution can be algebraic or calculated. Please use rewrites to solve the equation.
;; // Example equations and solutions:
;; // 1
;; // equation: (x + 50) * 10 - 15 = 10
;; // solution: x = (((10 + 15) / 10) - 50)
;; // 2
;; // equation: ((x + 10) + 30) = 10 + 20
;; // solution: x = (((10 + 20) - 30) - 10)
;; // 3
;; // equation: ((x + 10) + (20 + 30)) = 10 + 20
;; // solution: x = (((10 + 20) - (20 + 30)) - 10)
;; // 4
;; // equation: ((20 + 30) + (x + 10)) = 10 + 20
;; // solution: x = (((10 + 20) - (20 + 30)) - 10)
;; // 5
;; // equation: (((3 * x) * 4) * 5) = 1
;; // solution: x = (((1 / 5) / 4) / 3)
;; // 6
;; // equation: (((3 / x) * 4) * 5) = 1
;; // solution: x = (3 / ((1 / 5) / 4))
;; // 7
;; // equation: (((3 / (x + 10)) * 4) * 5) = 1
;; // solution: x = ((3 / ((1 / 5) / 4)) - 10)
;;
;; // Output solutions are just examples and can vary. More the solver can parse and solve better.
;; // It’s tough to build a solver which can solve all the cases in the allotted time however it’s still possible.
;; // You can use any library for parser however you’d need to write solver yourself.
(defn ->tree [v]
(if (coll? v)
(if (= 1 (count v))
(->tree (first v))
(let [v (vec v)
i (max (.lastIndexOf v :+) (.lastIndexOf v :-))
j (max (.lastIndexOf v :*) (.lastIndexOf v :/))
k (if (neg? i) j i)]
[(->tree (subvec v 0 k)) (get v k) (->tree (subvec v (inc k)))]))
v))
(defn read-tree [s]
(-> (str "(" s ")")
(str/escape {\+ " :+ "
\- " :- "
\* " :* "
\/ " :/ "})
read-string
->tree))
(defn show-tree [t]
(if (coll? t)
(let [[l o r] t]
(str "(" (show-tree l) " " (name o) " " (show-tree r) ")"))
t))
(defn eval-tree [t]
(if (coll? t)
(let [[l o r] t]
(({:+ +, :- -, :* *, :/ /} o) (eval-tree l) (eval-tree r)))
t))
(defn has-x? [t]
(if (coll? t)
(let [[l _ r] t]
(or (has-x? l) (has-x? r)))
(= t 'x)))
(defn solve [t v]
(loop [t t
v v]
(println (show-tree t) "=" (show-tree v))
(if (coll? t)
(let [[l o r] t]
(if (has-x? l)
(case o
:+ (recur l [v :- r])
:- (recur l [v :+ r])
:* (recur l [v :/ r])
:/ (recur l [v :* r]))
(case o
:+ (recur r [v :- l])
:- (recur r [l :- v])
:* (recur r [v :/ l])
:/ (recur r [l :/ v]))))
v)))
(defn task [s]
(let [[e v] (map read-tree (str/split s #"\=" 2))
r (solve e v)]
[(show-tree r) (eval-tree r)]))
(doseq [[i eq sol] [[1 "(x + 50) * 10 - 15 = 10" "(((10 + 15) / 10) - 50)"]
[2 "((x + 10) + 30) = 10 + 20" "(((10 + 20) - 30) - 10)"]
[3 "((x + 10) + (20 + 30)) = 10 + 20" "(((10 + 20) - (20 + 30)) - 10)"]
[4 "((20 + 30) + (x + 10)) = 10 + 20" "(((10 + 20) - (20 + 30)) - 10)"]
[5 "(((3 * x) * 4) * 5) = 1" "(((1 / 5) / 4) / 3)"]
[6 "(((3 / x) * 4) * 5) = 1" "(3 / ((1 / 5) / 4))"]
[7 "(((3 / (x + 10)) * 4) * 5) = 1" "((3 / ((1 / 5) / 4)) - 10)"]]]
(println)
(println "equation" i ":" eq)
(let [[sy val] (task eq)]
(if (= sy sol)
(println "solution: x =" sy "=" val)
(println "error!!!: x =" sy "=" val "!=" sol))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment