-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday7.py
87 lines (71 loc) · 2.36 KB
/
day7.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import time
def parse_input(filename: str) -> list[str]:
with open(filename) as f:
return f.readlines()
def get_num_digits(n):
if n == 0:
return 1
count = 0
while n:
count += 1
n //= 10
return count
def evaluate_ltr(params, operators):
if not operators:
return params[0]
result = params[0]
for i in range(len(operators)):
if operators[i] == '*':
result *= params[i + 1]
elif operators[i] == '+':
result += params[i + 1]
elif operators[i] == '||':
result = result * (10 ** get_num_digits(params[i+1])) + params[i+1]
return result
def backtrack(test: int, params: list[int], operators: list[str], concat: bool) -> int:
if len(operators) == len(params) - 1:
return evaluate_ltr(params, operators) == test
operators.append('+')
if backtrack(test, params, operators, True):
return True
operators.pop()
operators.append('*')
if backtrack(test, params, operators, True):
return True
operators.pop()
if concat:
operators.append('||')
if backtrack(test, params, operators, True):
return True
operators.pop()
return False
def part_one(strings: list[str]) -> int | dict[int, list[int]]:
count = 0
invalid_tests = {}
for line in strings:
test_raw, params_raw = line.split(':')
test = int(test_raw)
params = list(map(int, params_raw.strip().split(' ')))
if backtrack(test, params, [], False):
count += test
else:
invalid_tests[test] = params
print(count)
return count, invalid_tests
def part_two(count, invalid_tests) -> None:
for test, params in invalid_tests.items():
if backtrack(test, params, [], True):
count += test
print(count)
def main(input_filename: str):
inp = parse_input(input_filename)
start_part_one = time.time()
count, items = part_one(inp)
start_part_two = time.time()
part_two(count, items)
end_time = time.time()
print(f"Part one took {start_part_two - start_part_one:.2f} seconds")
print(f"Part two took {end_time - start_part_two:.2f} seconds")
if __name__ == "__main__":
main("input.txt")
# main("sample.txt")