[wip]: simplifying multilinear polynomials

This commit is contained in:
Thibaud Gasser 2024-01-24 17:14:24 +01:00
parent 3c21bf5a7b
commit 751e369a99
2 changed files with 111 additions and 0 deletions

87
simplify-poly/solution.py Normal file
View 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
View 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")