diff --git a/brainfuck-to-c-translator/solution.py b/brainfuck-to-c-translator/solution.py index 64ce12c..82a384c 100644 --- a/brainfuck-to-c-translator/solution.py +++ b/brainfuck-to-c-translator/solution.py @@ -4,14 +4,14 @@ from dataclasses import dataclass class OpKind(Enum): - LEFT = '<' - RIGHT = '>' - INC = '+' - DEC = '-' - INPT = ',' - OUTP = '.' - JMPZ = '[' - JMPNZ = ']' + LEFT = "<" + RIGHT = ">" + INC = "+" + DEC = "-" + INPT = "," + OUTP = "." + JMPZ = "[" + JMPNZ = "]" @dataclass @@ -33,7 +33,6 @@ def optimize(tokens): if len(new_tokens) <= 1: return new_tokens - tokens = otpi_cancel_opposing(new_tokens) while len(new_tokens := otpi_cancel_opposing(tokens)) != len(tokens): tokens = new_tokens @@ -49,7 +48,10 @@ def opti_collapse_tokens(tokens): new_tokens.append(next_token) continue current_token = new_tokens.pop() - if current_token.kind == next_token.kind and str(current_token.kind.value) in "<>+-": + if ( + current_token.kind == next_token.kind + and str(current_token.kind.value) in "<>+-" + ): current_token.operand += 1 new_tokens.append(current_token) else: @@ -66,8 +68,11 @@ def otpi_cancel_opposing(tokens): new_tokens.append(next_token) continue current_token = new_tokens.pop() - if (current_token.kind.value + next_token.kind.value in ("+-", "-+", "<>", "><", "[]") - and current_token.operand == next_token.operand): + if ( + current_token.kind.value + next_token.kind.value + in ("+-", "-+", "<>", "><", "[]") + and current_token.operand == next_token.operand + ): continue else: new_tokens.append(current_token) @@ -81,18 +86,28 @@ def generate_code(tokens): # code generation for token in tokens: match token.kind: - case OpKind.LEFT: out.append(f"{' ' * nest * 2}p -= {token.operand};\n") - case OpKind.RIGHT: out.append(f"{' ' * nest * 2}p += {token.operand};\n") - case OpKind.INC: out.append(f"{' ' * nest * 2}*p += {token.operand};\n") - case OpKind.DEC: out.append(f"{' ' * nest * 2}*p -= {token.operand};\n") - case OpKind.INPT: out.append(f"{' ' * nest * 2}*p = getchar();\n") - case OpKind.OUTP: out.append(f"{' ' * nest * 2}putchar(*p);\n") - case OpKind.JMPZ: out.append(f"{' ' * nest * 2}" + "if (*p) do {\n");nest += 1 - case OpKind.JMPNZ: nest -= 1;out.append(f"{' ' * nest * 2}" + "} while (*p);\n") - + case OpKind.LEFT: + out.append(f"{' ' * nest * 2}p -= {token.operand};\n") + case OpKind.RIGHT: + out.append(f"{' ' * nest * 2}p += {token.operand};\n") + case OpKind.INC: + out.append(f"{' ' * nest * 2}*p += {token.operand};\n") + case OpKind.DEC: + out.append(f"{' ' * nest * 2}*p -= {token.operand};\n") + case OpKind.INPT: + out.append(f"{' ' * nest * 2}*p = getchar();\n") + case OpKind.OUTP: + out.append(f"{' ' * nest * 2}putchar(*p);\n") + case OpKind.JMPZ: + out.append(f"{' ' * nest * 2}" + "if (*p) do {\n") + nest += 1 + case OpKind.JMPNZ: + nest -= 1 + out.append(f"{' ' * nest * 2}" + "} while (*p);\n") + if nest < 0: return "Error!" - + if nest != 0: return "Error!" diff --git a/simplify-poly/solution.py b/simplify-poly/solution.py index 366e030..d58fabb 100644 --- a/simplify-poly/solution.py +++ b/simplify-poly/solution.py @@ -3,14 +3,15 @@ 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 @@ -18,47 +19,37 @@ class Term: 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) + r = Term(self.coef + other.coef, self.variables) 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) - + if len(self.variables) == len(other.variables): + return self.variables < other.variables + + return len(self.variables) < len(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 = '', [], [] + sign, coef, variables = "", [], [] for n in inp: - if n == '-': - sign = '-' + if n == "-": + sign = "-" elif n.isnumeric(): coef.append(n) elif n.isalpha(): - variables.append(n) - - c = -1 if sign == '-' else 1 + 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 +def simplify_terms(terms: [Term]) -> [Term]: simplified_terms = [] for term in terms: if not simplified_terms: @@ -70,14 +61,15 @@ def simplify(poly): res = previous + term if res.coef != 0: simplified_terms.append(res) - except ArithmeticError as e: - print("no match") + except ArithmeticError: # terms not compatible to be added simplified_terms.append(previous) simplified_terms.append(term) - - # build output str + return simplified_terms + + +def poly_to_str(terms: [Term]) -> str: res = "" - for term in simplified_terms: + for term in terms: s = str(term) if res and not s.startswith("-"): res += "+" @@ -85,3 +77,10 @@ def simplify(poly): else: res += s return res + + +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)