86 lines
1.9 KiB
Python
86 lines
1.9 KiB
Python
with open('input.text', 'r') as file:
|
|
data: list[str] = file.readlines()
|
|
|
|
# Parse Data
|
|
|
|
class Rule:
|
|
subject: int
|
|
constraint: int
|
|
|
|
def __init__(self, n: int, other: int):
|
|
self.subject = n
|
|
self.constraint = other
|
|
|
|
def __str__(self) -> str:
|
|
return f'{self.subject}|{self.constraint}'
|
|
|
|
class Update:
|
|
nums: list[int]
|
|
|
|
def __init__(self, ns: list[int]):
|
|
self.nums = ns
|
|
|
|
def check_rule(self, rule: Rule) -> bool:
|
|
if rule.subject in self.nums and rule.constraint in self.nums:
|
|
if self.nums.index(rule.subject) > self.nums.index(rule.constraint):
|
|
return False
|
|
|
|
return True
|
|
|
|
def check_ruleset(self, ruleset: list[Rule]) -> Rule:
|
|
for rule in ruleset:
|
|
if not self.check_rule(rule):
|
|
return rule
|
|
|
|
return None
|
|
|
|
def fix_rule(self, rule: Rule) -> None:
|
|
if rule.subject not in self.nums and rule.constraint not in self.nums:
|
|
return None
|
|
|
|
si: int = self.nums.index(rule.subject)
|
|
ci: int = self.nums.index(rule.constraint)
|
|
|
|
self.nums[si] = rule.constraint
|
|
self.nums[ci] = rule.subject
|
|
|
|
def get_middle_num(self) -> int:
|
|
return self.nums[int(len(self.nums) / 2)]
|
|
|
|
def __str__(self) -> str:
|
|
return str(self.nums)
|
|
|
|
|
|
rules: list[Rule] = []
|
|
updates: list[Update] = []
|
|
|
|
for line in data:
|
|
if '|' in line:
|
|
n1, n2 = [int(n) for n in line.split('|')]
|
|
rules.append(Rule(n1, n2))
|
|
elif ',' in line:
|
|
nums = [int(n) for n in line.split(',')]
|
|
updates.append(Update(nums))
|
|
|
|
# Part 1
|
|
total = 0
|
|
for update in updates:
|
|
if update.check_ruleset(rules):
|
|
total += update.get_middle_num()
|
|
|
|
print(f'Part 1: {total}')
|
|
|
|
# Part 2
|
|
total = 0
|
|
for update in updates:
|
|
fixed = False
|
|
while r := update.check_ruleset(rules):
|
|
update.fix_rule(r)
|
|
fixed = True
|
|
|
|
if fixed:
|
|
total += update.get_middle_num()
|
|
|
|
print(f'Part 2: {total}')
|
|
|