[py] Port 2017_08

This commit is contained in:
Joscha 2022-12-06 19:47:17 +01:00
parent 988c2098e6
commit cd785a40b3
4 changed files with 95 additions and 101 deletions

View file

@ -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)

View file

@ -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

View file

@ -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,

93
py/aoc/y2017/d08.py Normal file
View 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}")