# Solve For X

You will be given an equation as a string and you will need to [solve for X](https://www.mathplacementreview.com/algebra/basic-algebra.php#solve-for-a-variable) and return x's value. For example: 

```python
solve_for_x('x - 5 = 20') # should return 25
solve_for_x('20 = 5 * x - 5') # should return 5
solve_for_x('5 * x = x + 8') # should return 2
solve_for_x('(5 - 3) * x = x + 2') # should return 2
```

NOTES:
 * All numbers will be whole numbers
 * Don't forget about the [order of operations](https://www.mathplacementreview.com/algebra/basic-algebra.php#order-of-operations).
 * If the random tests don't pass the first time, just run them again.

Source: codewars | Difficulty: EASY
Tags: Fundamentals

Mathematics

Ad-hoc

Starter code: def solve_for_x(equation):
	

Solutions:
from itertools import count

def solve_for_x(equation):
	return next((x for n in count(0) for x in [n, -n] if eval(equation.replace('x', str(x)).replace('=', '=='))))


import re

def solve_for_x(equation):
	(left, right) = equation.split('=')
	answer = False
	TrialAndErrorRipMs = -1000
	while answer == False:
		FinalLeft = re.sub('x', str(TrialAndErrorRipMs), left)
		FinalRight = re.sub('x', str(TrialAndErrorRipMs), right)
		if eval(FinalLeft) == eval(FinalRight):
			return TrialAndErrorRipMs
		TrialAndErrorRipMs += 1


def solve_for_x(equation):
	left_side = equation.split('=')[0]
	right_side = equation.split('=')[1]
	for x in range(-1000, 1000):
		if eval(left_side) == eval(right_side):
			return x


def solve_for_x(equation):
	for x in range(-100, 1001):
		if eval(equation.replace('=', '==')):
			return x


from itertools import count

def solve_for_x(equation):
	equation = equation.replace('=', '==')
	for x in count():
		if eval(equation):
			return x
		x = -x
		if eval(equation):
			return x


def solve_for_x(equation):
	(left, right) = equation.split('=')
	for x in range(-1000, 1000):
		if eval(left) == eval(right):
			return x


def solve_for_x(equation):
	p = equation.split()
	for i in range(0, len(p)):
		if p[i] == '=':
			p[i] = '=='
	t = p.index('x')
	for x in range(-1000, 1000):
		p[t] = str(x)
		if eval(''.join(p)):
			return x


def solve_for_x(s):
	for i in range(-1000, 1000):
		if eval(s.replace('x', str(i)).replace('=', '==')):
			return i


class Exp:

	def __init__(self, s):
		self.a = 1
		self.p = 0
		if s[-1] == 'x':
			self.p = 1
			s = s[:-1]
		if 0 < len(s):
			self.a *= int(s)

	def __add__(self, other):
		if self.p == other.p:
			self.a += other.a
			return self
		else:
			return Equ([self, other])

	def __sub__(self, other):
		if self.p == other.p:
			self.a -= other.a
			return self
		else:
			return Equ([self, Exp('-1') * other])

	def __mul__(self, other):
		self.p += other.p
		self.a *= other.a
		return self

	def __div__(self, other):
		self.p -= other.p
		self.a /= other.a
		return self

	def __str__(self):
		s = ''
		if self.a != 0:
			s += str(self.a)
		if self.p == 1:
			s += 'x'
		if s == '':
			s += '0'
		return s

class Equ:

	def __init__(self, exp):
		self.exp = dict()
		for e in exp:
			if e.p not in self.exp:
				self.exp[e.p] = e
			else:
				self.exp[e.p] += e

	def __add__(self, other):
		if type(other) == Exp:
			other = Equ([other])
		for p in other.exp:
			if p in self.exp:
				self.exp[p] += other.exp[p]
			else:
				self.exp[p] = other.exp[p]
		return self

	def __sub__(self, other):
		if type(other) == Exp:
			other = Equ([other])
		for p in other.exp:
			if p in self.exp:
				self.exp[p] -= other.exp[p]
			else:
				self.exp[p] = Exp('-1') * other.exp[p]
		return self

	def __mul__(self, other):
		if type(other) == Exp:
			other = Equ([other])
		res = None
		for p1 in other.exp:
			temp_res = []
			for p2 in self.exp:
				temp_res.append(self.exp[p2] * other.exp[p1])
			if res is None:
				res = Equ(temp_res)
			else:
				res += Equ(temp_res)
		return self

	def __div__(self, other):
		if type(other) == Exp:
			other = Equ([other])
		res = None
		for p1 in other.exp:
			temp_res = []
			for p2 in self.exp:
				temp_res.append(self.exp[p2] / other.exp[p1])
			if res is None:
				res = Equ(temp_res)
			else:
				res += Equ(temp_res)
		return self

	def __str__(self):
		s = ''
		for p in self.exp:
			s += ' (' + str(self.exp[p]) + ') +'
		return s[:-1]

	def get_power(self, p):
		return self.exp[p] if p in self.exp else Exp('0') if p == 0 else Exp('0x')

def build1(s):
	s = s.replace(' ', '')
	stack = []
	s += '!'
	if s[0] == '-':
		s = '0' + s
	j = 0
	for i in range(len(s)):
		if s[i] in ['+', '-', '*', '/', '(', ')', '!']:
			if j < i:
				stack.append(s[j:i])
			stack.append(s[i])
			j = i + 1
	stack.remove('!')
	for (i, x) in enumerate(stack):
		if x not in ['+', '-', '*', '/', '(', ')', '!']:
			stack[i] = Exp(x)
	return stack

def build2(s):
	while ')' in s:
		end = s.index(')')
		start = end
		while s[start] != '(':
			start -= 1
		s = s[:start] + [build2(s[start + 1:end])] + s[end + 1:]
	op = {'+': lambda x, y: x + y, '-': lambda x, y: x - y, '*': lambda x, y: x * y, '/': lambda x, y: x.__div__(y)}
	i = 2
	for order in [0, 1]:
		i = 2
		while i < len(s):
			if order == 0 and s[i - 1] in ['*', '/'] or (order == 1 and s[i - 1] in ['+', '-']):
				s[i - 2] = op[s[i - 1]](s[i - 2], s[i])
				s.pop(i)
				s.pop(i - 1)
			else:
				i += 2
	return s[0]

def build(s):
	stack = build1(s)
	equ = build2(stack)
	if type(equ) == Exp:
		equ = Equ([equ])
	return equ

def solve_for_x(equation):
	(l, r) = equation.split(' = ')
	(l, r) = (build(l), build(r))
	(l, r) = (l.get_power(1) - r.get_power(1), r.get_power(0) - l.get_power(0))
	return r.a / l.a