[wip]: simplifying multilinear polynomials
This commit is contained in:
parent
3c21bf5a7b
commit
751e369a99
87
simplify-poly/solution.py
Normal file
87
simplify-poly/solution.py
Normal file
@ -0,0 +1,87 @@
|
||||
# https://www.codewars.com/kata/55f89832ac9a66518f000118/
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class Term:
|
||||
coef: int
|
||||
variables: str
|
||||
|
||||
def __repr__(self):
|
||||
return f"Term(coef={self.coef}, vars={self.variables})"
|
||||
|
||||
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):
|
||||
print(f"add {self} {other}")
|
||||
if self.variables == other.variables:
|
||||
r = Term(self.coef+other.coef, self.variables)
|
||||
print(r)
|
||||
return r
|
||||
else:
|
||||
print(self.variables, other.variables)
|
||||
raise ArithmeticError("Variables do not match")
|
||||
|
||||
def __lt__(self, other):
|
||||
return (len(self.variables) < len(other.variables)) and (self.variables < other.variables)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.coef == other.coef and self.variables == other.variables
|
||||
|
||||
|
||||
def parse_term(inp: str) -> Term:
|
||||
sign, coef, variables = '', [], []
|
||||
for n in inp:
|
||||
if n == '-':
|
||||
sign = '-'
|
||||
elif n.isnumeric():
|
||||
coef.append(n)
|
||||
elif n.isalpha():
|
||||
variables.append(n)
|
||||
|
||||
c = -1 if sign == '-' else 1
|
||||
c *= int("".join(coef)) if coef else 1
|
||||
return Term(c, sorted(variables))
|
||||
|
||||
|
||||
def simplify(poly):
|
||||
print(poly)
|
||||
|
||||
# parse
|
||||
pattern = r"([+-]?\d*\w+)"
|
||||
terms = sorted(parse_term(t) for t in re.findall(pattern, poly))
|
||||
|
||||
print(terms)
|
||||
|
||||
# simplify
|
||||
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)
|
||||
except ArithmeticError as e:
|
||||
print("no match")
|
||||
simplified_terms.append(previous)
|
||||
simplified_terms.append(term)
|
||||
|
||||
# build output str
|
||||
res = ""
|
||||
for term in simplified_terms:
|
||||
s = str(term)
|
||||
if res and not s.startswith("-"):
|
||||
res += "+"
|
||||
res += s
|
||||
else:
|
||||
res += s
|
||||
return res
|
24
simplify-poly/tests.py
Normal file
24
simplify-poly/tests.py
Normal file
@ -0,0 +1,24 @@
|
||||
import codewars_test as test
|
||||
from solution import simplify
|
||||
|
||||
test.it("Test reduction by equivalence")
|
||||
test.assert_equals(simplify("dc+dcba"), "cd+abcd")
|
||||
|
||||
test.assert_equals(simplify("2xy-yx"),"xy")
|
||||
|
||||
test.assert_equals(simplify("-a+5ab+3a-c-2a"),"-c+5ab")
|
||||
|
||||
test.it("Test monomial length ordering")
|
||||
test.assert_equals(simplify("-abc+3a+2ac"),"3a+2ac-abc")
|
||||
|
||||
test.assert_equals(simplify("xyz-xz"),"-xz+xyz")
|
||||
|
||||
test.it("Test lexicographic ordering")
|
||||
test.assert_equals(simplify("a+ca-ab"),"a-ab+ac")
|
||||
|
||||
test.assert_equals(simplify("xzy+zby"),"byz+xyz")
|
||||
|
||||
test.it("Test no leading +")
|
||||
test.assert_equals(simplify("-y+x"),"x-y")
|
||||
|
||||
test.assert_equals(simplify("y-x"),"-x+y")
|
Loading…
Reference in New Issue
Block a user