-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpart_1.py
100 lines (81 loc) · 2.31 KB
/
part_1.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
88
89
90
91
92
93
94
95
96
97
98
99
100
from itertools import permutations
import numpy as np
content = []
# Read input lines and filter lines matching the pattern
with open("input.txt", "r") as f:
for line in f:
if "A" in line and any(char.isdigit() for char in line[:3]):
content.append(line.strip())
# Positions and directions as numpy vectors
POSITIONS = {
"7": np.array([0, 0]),
"8": np.array([0, 1]),
"9": np.array([0, 2]),
"4": np.array([1, 0]),
"5": np.array([1, 1]),
"6": np.array([1, 2]),
"1": np.array([2, 0]),
"2": np.array([2, 1]),
"3": np.array([2, 2]),
"0": np.array([3, 1]),
"A": np.array([3, 2]),
"^": np.array([0, 1]),
"a": np.array([0, 2]),
"<": np.array([1, 0]),
"v": np.array([1, 1]),
">": np.array([1, 2]),
}
DIRECTIONS = {
"^": np.array([-1, 0]),
"v": np.array([1, 0]),
"<": np.array([0, -1]),
">": np.array([0, 1]),
}
def seeToMoveSet(start, fin, avoid=np.array([0, 0])):
delta = fin - start
string = ""
dx, dy = delta
# Generate moves
if dx < 0:
string += "^" * abs(dx)
else:
string += "v" * dx
if dy < 0:
string += "<" * abs(dy)
else:
string += ">" * dy
# Generate unique permutations of moves
rv = [
"".join(p) + "a"
for p in set(permutations(string))
if not any(
(sum(DIRECTIONS[move] for move in p[:i]) + start == avoid).all()
for i in range(len(p))
)
]
return rv if rv else ["a"]
memoization = {}
def minLength(s, lim=2, depth=0):
key = (s, depth, lim)
if key in memoization:
return memoization[key]
avoid = np.array([3, 0]) if depth == 0 else np.array([0, 0])
cur = POSITIONS["A"] if depth == 0 else POSITIONS["a"]
length = 0
for char in s:
nextCurrent = POSITIONS[char]
moveSet = seeToMoveSet(cur, nextCurrent, avoid)
if depth == lim:
length += len(moveSet[0])
else:
length += min(minLength(move, lim, depth + 1) for move in moveSet)
cur = nextCurrent
memoization[key] = length
return length
def sumOfFiveCodeComplexities() -> int:
complexityA = 0
for code in content:
lengthA = minLength(code)
numeric = int(code[:3])
complexityA += lengthA * numeric
return complexityA