From 751e369a9900d05f266b88e106113715dee1bf27 Mon Sep 17 00:00:00 2001 From: "GASSER Thibaud (PRESTA EXT)" Date: Wed, 24 Jan 2024 17:14:24 +0100 Subject: [PATCH] [wip]: simplifying multilinear polynomials --- simplify-poly/solution.py | 87 +++++++++++++++++++++++++++++++++++++++ simplify-poly/tests.py | 24 +++++++++++ 2 files changed, 111 insertions(+) create mode 100644 simplify-poly/solution.py create mode 100644 simplify-poly/tests.py diff --git a/simplify-poly/solution.py b/simplify-poly/solution.py new file mode 100644 index 0000000..366e030 --- /dev/null +++ b/simplify-poly/solution.py @@ -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 diff --git a/simplify-poly/tests.py b/simplify-poly/tests.py new file mode 100644 index 0000000..aa5ac53 --- /dev/null +++ b/simplify-poly/tests.py @@ -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") \ No newline at end of file