70 lines
1.8 KiB
Python
70 lines
1.8 KiB
Python
#!/usr/bin/env python
|
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
|
|
|
# Author: Sebastian Mark
|
|
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
|
|
|
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
|
|
|
from itertools import product
|
|
|
|
|
|
def readinput():
|
|
with open("input", "r", encoding="utf-8") as file:
|
|
lines = file.readlines()
|
|
return lines
|
|
|
|
|
|
def operator_left_to_right(numbers: list, operators: list) -> int:
|
|
result = numbers[0]
|
|
|
|
for i, op in enumerate(operators):
|
|
if op == "+":
|
|
result += numbers[i + 1]
|
|
elif op == "*":
|
|
result *= numbers[i + 1]
|
|
elif op == "||":
|
|
result = int(str(result) + str(numbers[i + 1]))
|
|
|
|
return result
|
|
|
|
|
|
def is_valid_calibration(target: int, numbers: list, operators: list) -> bool:
|
|
for op_iteration in product(operators, repeat=len(numbers) - 1):
|
|
result = operator_left_to_right(numbers, op_iteration)
|
|
if result == target:
|
|
return True
|
|
return False
|
|
|
|
|
|
def get_calibration(line: list) -> (int, list):
|
|
target = int(line.split(":")[0])
|
|
numbers = list(map(int, line.split()[1:]))
|
|
|
|
return target, numbers
|
|
|
|
|
|
def main():
|
|
calibrations = readinput()
|
|
|
|
# part 1
|
|
count = 0
|
|
operators = ["+", "*"]
|
|
for line in calibrations:
|
|
target, numbers = get_calibration(line)
|
|
if is_valid_calibration(target, numbers, operators):
|
|
count += target
|
|
print("Calibration result: %d" % count)
|
|
|
|
# part 2
|
|
count = 0
|
|
operators = ["+", "*", "||"]
|
|
for line in calibrations:
|
|
target, numbers = get_calibration(line)
|
|
if is_valid_calibration(target, numbers, operators):
|
|
count += target
|
|
print("Calibration result (with concat): %d" % count)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|