diff --git a/2024/day7/main.py b/2024/day7/main.py index 5835876..4bd3423 100644 --- a/2024/day7/main.py +++ b/2024/day7/main.py @@ -1,8 +1,30 @@ -import re - -with open('test.text', 'r') as file: +with open('input.text', 'r') as file: data: list[str] = file.readlines() +class Operator: + def __init__(self): + pass + +class Add(Operator): + def __init__(self): + pass + + def compute(self, x: int, y: int) -> int: + return x + y + +class Multiply(Operator): + def __init__(self): + pass + + def compute(self, x: int, y: int) -> int: + return x * y + +class Concat(Operator): + def __init__(self): + pass + + def compute(self, x: int, y: int) -> int: + return int(str(x) + str(y)) class Equation: result: int @@ -12,77 +34,60 @@ class Equation: self.result = result self.constants = constants - def is_valid_eq(self, eq: str) -> bool: - tokens: list[str] = re.findall('\d+|\+|\*', eq) + def is_valid_eq(self, eq: list[int | Operator]) -> bool: r = None - op = lambda x,y: x + y - for token in tokens: - if not r and token.isnumeric(): - r = int(token) - elif token == '+': - op = lambda x,y: x + y - elif token == '*': - op = lambda x,y: x * y - else: - r = op(r, int(token)) - + for i, token in enumerate(eq): + match token: + case Operator(): + r = token.compute(r, eq[i + 1]) + case int(): + if not r: + r = token return r == self.result - - def is_valid(self, s: str | None) -> bool: - if s == None: - s = '' + + def is_valid(self, eq: list[int | Operator]) -> bool: + if not eq: + eq = [] for c in self.constants: - s += (str(c) + ' ') - return self.is_valid(s[:-1]) - elif ' ' in s: - s1 = s.replace(' ', '+', 1) - s2 = s.replace(' ', '*', 1) - return self.is_valid(s1) or self.is_valid(s2) - else: - return self.is_valid_eq(s) - - def is_valid2(self, s: str | None) -> bool: - if s == None: - s = '' + eq.append(c) + eq.append(' ') + eq = eq[:-1] + + for i, c in enumerate(eq): + if c == ' ': + new_eq1 = eq.copy() + new_eq2 = eq.copy() + + new_eq1[i] = Add() + new_eq2[i] = Multiply() + + return self.is_valid(new_eq1) or self.is_valid(new_eq2) + + return self.is_valid_eq(eq) + + def is_valid2(self, eq: list[int | Operator]) -> bool: + if not eq: + eq = [] for c in self.constants: - s += (str(c) + ' ') - return self.is_valid2(s[:-1]) - elif ' ' in s: - s1 = s.replace(' ', '+', 1) - s2 = s.replace(' ', '*', 1) + eq.append(c) + eq.append(' ') + eq = eq[:-1] - # We do the || operator right here - if s.count(' ') >= 1: - tokens: list[str] = re.findall('\d+|\+|\*| ', s) - space_i = tokens.index(' ') + for i, c in enumerate(eq): + if c == ' ': + new_eq1 = eq.copy() + new_eq2 = eq.copy() + new_eq3 = eq.copy() - new_num = tokens[space_i - 1].strip() + tokens[space_i + 1].strip() - new_tokens = tokens[:space_i - 1] - new_i = len(new_tokens) - new_tokens.append(new_num) - new_tokens.extend(tokens[space_i + 2:]) - s3 = '' - print(new_tokens) - for i, token in enumerate(new_tokens): - if token == ' ': - continue - if i > new_i - 1: - s3 += (token + ' ') - else: - s3 += token + new_eq1[i] = Add() + new_eq2[i] = Multiply() + new_eq3[i] = Concat() - print(s) - print(s3) - # exit() - - return self.is_valid2(s1) or self.is_valid2(s2) or self.is_valid2(s3[:-1]) - else: - return self.is_valid2(s1) or self.is_valid2(s2) - else: - return self.is_valid_eq(s) + return self.is_valid2(new_eq1) or self.is_valid2(new_eq2) or self.is_valid2(new_eq3) + return self.is_valid_eq(eq) equations: list[Equation] = [] diff --git a/2024/day7/test.text b/2024/day7/test.text index 9bd7043..87b8b25 100644 --- a/2024/day7/test.text +++ b/2024/day7/test.text @@ -1 +1,9 @@ -7290: 6 8 6 15 \ No newline at end of file +190: 10 19 +3267: 81 40 27 +83: 17 5 +156: 15 6 +7290: 6 8 6 15 +161011: 16 10 13 +192: 17 8 14 +21037: 9 7 18 13 +292: 11 6 16 20 \ No newline at end of file