[py] Port 2017_08
This commit is contained in:
parent
988c2098e6
commit
cd785a40b3
4 changed files with 95 additions and 101 deletions
93
py/aoc/y2017/d08.py
Normal file
93
py/aoc/y2017/d08.py
Normal file
|
|
@ -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}")
|
||||
Loading…
Add table
Add a link
Reference in a new issue