2024-01-24 16:14:24 +00:00
|
|
|
# https://www.codewars.com/kata/55f89832ac9a66518f000118/
|
|
|
|
|
|
|
|
import re
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
2024-01-25 16:26:34 +00:00
|
|
|
|
2024-01-24 16:14:24 +00:00
|
|
|
@dataclass
|
|
|
|
class Term:
|
|
|
|
coef: int
|
|
|
|
variables: str
|
2024-01-25 16:26:34 +00:00
|
|
|
|
2024-01-24 16:14:24 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return f"Term(coef={self.coef}, vars={self.variables})"
|
2024-01-25 16:26:34 +00:00
|
|
|
|
2024-01-24 16:14:24 +00:00
|
|
|
def __str__(self):
|
|
|
|
a = str(self.coef) if self.coef != 1 else ""
|
|
|
|
a = "-" if a == "-1" else a
|
|
|
|
b = "".join(self.variables)
|
|
|
|
return f"{a}{b}"
|
|
|
|
|
|
|
|
def __add__(self, other):
|
|
|
|
if self.variables == other.variables:
|
2024-01-25 16:26:34 +00:00
|
|
|
r = Term(self.coef + other.coef, self.variables)
|
2024-01-24 16:14:24 +00:00
|
|
|
return r
|
|
|
|
raise ArithmeticError("Variables do not match")
|
|
|
|
|
|
|
|
def __lt__(self, other):
|
2024-01-25 16:26:34 +00:00
|
|
|
if len(self.variables) == len(other.variables):
|
|
|
|
return self.variables < other.variables
|
|
|
|
|
|
|
|
return len(self.variables) < len(other.variables)
|
|
|
|
|
2024-01-24 16:14:24 +00:00
|
|
|
def __eq__(self, other):
|
|
|
|
return self.coef == other.coef and self.variables == other.variables
|
|
|
|
|
|
|
|
|
|
|
|
def parse_term(inp: str) -> Term:
|
2024-01-25 16:26:34 +00:00
|
|
|
sign, coef, variables = "", [], []
|
2024-01-24 16:14:24 +00:00
|
|
|
for n in inp:
|
2024-01-25 16:26:34 +00:00
|
|
|
if n == "-":
|
|
|
|
sign = "-"
|
2024-01-24 16:14:24 +00:00
|
|
|
elif n.isnumeric():
|
|
|
|
coef.append(n)
|
|
|
|
elif n.isalpha():
|
2024-01-25 16:26:34 +00:00
|
|
|
variables.append(n)
|
|
|
|
|
|
|
|
c = -1 if sign == "-" else 1
|
2024-01-24 16:14:24 +00:00
|
|
|
c *= int("".join(coef)) if coef else 1
|
|
|
|
return Term(c, sorted(variables))
|
|
|
|
|
|
|
|
|
2024-01-25 16:26:34 +00:00
|
|
|
def simplify_terms(terms: [Term]) -> [Term]:
|
2024-01-24 16:14:24 +00:00
|
|
|
simplified_terms = []
|
|
|
|
for term in terms:
|
|
|
|
if not simplified_terms:
|
|
|
|
simplified_terms.append(term)
|
|
|
|
continue
|
|
|
|
|
|
|
|
previous = simplified_terms.pop()
|
|
|
|
try:
|
|
|
|
res = previous + term
|
|
|
|
if res.coef != 0:
|
|
|
|
simplified_terms.append(res)
|
2024-01-25 16:26:34 +00:00
|
|
|
except ArithmeticError: # terms not compatible to be added
|
2024-01-24 16:14:24 +00:00
|
|
|
simplified_terms.append(previous)
|
|
|
|
simplified_terms.append(term)
|
2024-01-25 16:26:34 +00:00
|
|
|
return simplified_terms
|
|
|
|
|
|
|
|
|
|
|
|
def poly_to_str(terms: [Term]) -> str:
|
2024-01-24 16:14:24 +00:00
|
|
|
res = ""
|
2024-01-25 16:26:34 +00:00
|
|
|
for term in terms:
|
2024-01-24 16:14:24 +00:00
|
|
|
s = str(term)
|
|
|
|
if res and not s.startswith("-"):
|
|
|
|
res += "+"
|
|
|
|
res += s
|
|
|
|
else:
|
|
|
|
res += s
|
|
|
|
return res
|
2024-01-25 16:26:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
def simplify(poly: str):
|
|
|
|
pattern = r"([+-]?\d*\w+)"
|
|
|
|
terms = sorted(parse_term(t) for t in re.findall(pattern, poly))
|
|
|
|
simplified_terms = simplify_terms(terms)
|
|
|
|
return poly_to_str(simplified_terms)
|