diff --git a/py/2017/08/solve.py b/py/2017/08/solve.py deleted file mode 100644 index 7db4242..0000000 --- a/py/2017/08/solve.py +++ /dev/null @@ -1,96 +0,0 @@ -import collections -import re -import sys - -# PART 1 - -class Instruction: - INSTRUCTION_RE = r"(\S+) (inc|dec) (-?\d+) if (\S+) (<|<=|>|>=|==|!=) (-?\d+)\n" - - def __init__(self, register, mode, amount, c_register, c_operator, c_amount): - self.register = register - self.mode = mode - self.amount = amount - self.c_register = c_register - self.c_operator = c_operator - self.c_amount = c_amount - - @classmethod - def from_line(cls, line): - match = re.fullmatch(cls.INSTRUCTION_RE, line) - - register = match.group(1) - mode = match.group(2) - amount = int(match.group(3)) - c_register = match.group(4) - c_operator = match.group(5) - c_amount = int(match.group(6)) - - return cls(register, mode, amount, c_register, c_operator, c_amount) - - def compare_to(self, n): - if self.c_operator == "<": - return n < self.c_amount - elif self.c_operator == "<=": - return n <= self.c_amount - elif self.c_operator == ">": - return n > self.c_amount - elif self.c_operator == ">=": - return n >= self.c_amount - elif self.c_operator == "==": - return n == self.c_amount - elif self.c_operator == "!=": - return n != self.c_amount - - def total(self): - if self.mode == "inc": - return self.amount - elif self.mode == "dec": - return -self.amount - -class Machine: - def __init__(self, instructions): - self.instructions = instructions - self.reset() - - def reset(self): - self.registers = collections.defaultdict(lambda: 0) - self.max_all_time = 0 - - @classmethod - def from_file(cls, filename): - instructions = [] - - with open(filename, "r") as f: - for line in f: - instructions.append(Instruction.from_line(line)) - - return cls(instructions) - - def execute_instruction(self, i): - c_amount = self.registers.get(i.c_register, 0) - if i.compare_to(c_amount): - self.registers[i.register] += i.total() - self.max_all_time = max(self.max_all_time, self.registers[i.register]) - - def execute(self): - for i in self.instructions: - self.execute_instruction(i) - - def max_register(self): - return max(self.registers.values()) - -# PART 2 - -def main(filename): - print(f"Solutions for {filename}") - machine = Machine.from_file(filename) - machine.reset() - machine.execute() - max_register = machine.max_register() - print(f"Part 1: {max_register}") - print(f"Part 2: {machine.max_all_time}") - -if __name__ == "__main__": - for filename in sys.argv[1:]: - main(filename) diff --git a/py/2017/08/test_input.txt b/py/2017/08/test_input.txt deleted file mode 100644 index 1fb12cf..0000000 --- a/py/2017/08/test_input.txt +++ /dev/null @@ -1,4 +0,0 @@ -b inc 5 if a > 1 -a inc 1 if b < 5 -c dec -10 if a >= 1 -c inc -20 if c == 10 diff --git a/py/aoc/__init__.py b/py/aoc/__init__.py index 3a6f2c2..bcb62f9 100644 --- a/py/aoc/__init__.py +++ b/py/aoc/__init__.py @@ -2,7 +2,7 @@ import sys import argparse from pathlib import Path -from .y2017 import d01, d02, d03, d04, d05, d06, d07 +from .y2017 import d01, d02, d03, d04, d05, d06, d07, d08 from .y2018 import d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, d11 from .y2020 import d10 from .y2021 import d14 @@ -16,6 +16,7 @@ DAYS = { "2017_05": y2017.d05.solve, "2017_06": y2017.d06.solve, "2017_07": y2017.d07.solve, + "2017_08": y2017.d08.solve, "2018_01": y2018.d01.solve, "2018_02": y2018.d02.solve, "2018_03": y2018.d03.solve, diff --git a/py/aoc/y2017/d08.py b/py/aoc/y2017/d08.py new file mode 100644 index 0000000..04149c9 --- /dev/null +++ b/py/aoc/y2017/d08.py @@ -0,0 +1,93 @@ +import collections +import re + +# PART 1 + + +class Instruction: + INSTRUCTION_RE = r"(\S+) (inc|dec) (-?\d+) if (\S+) (<|<=|>|>=|==|!=) (-?\d+)" + + def __init__(self, register, mode, amount, c_register, c_operator, c_amount): + self.register = register + self.mode = mode + self.amount = amount + self.c_register = c_register + self.c_operator = c_operator + self.c_amount = c_amount + + @classmethod + def from_line(cls, line): + match = re.fullmatch(cls.INSTRUCTION_RE, line) + + register = match.group(1) + mode = match.group(2) + amount = int(match.group(3)) + c_register = match.group(4) + c_operator = match.group(5) + c_amount = int(match.group(6)) + + return cls(register, mode, amount, c_register, c_operator, c_amount) + + def compare_to(self, n): + if self.c_operator == "<": + return n < self.c_amount + elif self.c_operator == "<=": + return n <= self.c_amount + elif self.c_operator == ">": + return n > self.c_amount + elif self.c_operator == ">=": + return n >= self.c_amount + elif self.c_operator == "==": + return n == self.c_amount + elif self.c_operator == "!=": + return n != self.c_amount + + def total(self): + if self.mode == "inc": + return self.amount + elif self.mode == "dec": + return -self.amount + + +class Machine: + def __init__(self, instructions): + self.instructions = instructions + self.reset() + + def reset(self): + self.registers = collections.defaultdict(lambda: 0) + self.max_all_time = 0 + + @classmethod + def from_str(cls, s): + instructions = [] + + for line in s.splitlines(): + instructions.append(Instruction.from_line(line)) + + return cls(instructions) + + def execute_instruction(self, i): + c_amount = self.registers.get(i.c_register, 0) + if i.compare_to(c_amount): + self.registers[i.register] += i.total() + self.max_all_time = max(self.max_all_time, self.registers[i.register]) + + def execute(self): + for i in self.instructions: + self.execute_instruction(i) + + def max_register(self): + return max(self.registers.values()) + + +# PART 2 + + +def solve(inputstr): + machine = Machine.from_str(inputstr) + machine.reset() + machine.execute() + max_register = machine.max_register() + print(f"Part 1: {max_register}") + print(f"Part 2: {machine.max_all_time}")