-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadvent_of_code_21.py
More file actions
183 lines (172 loc) · 5.43 KB
/
advent_of_code_21.py
File metadata and controls
183 lines (172 loc) · 5.43 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import itertools
def swap(inp, i1, i2):
if i1 < len(inp) and i2 < len(inp):
inp[i1], inp[i2] = inp[i2], inp[i1]
return inp
def rotate_right(inp, i):
return inp[-i:] + inp[:-i]
def rotate_left(inp, i):
return inp[i:] + inp[:i]
def parse_line(line, password):
line = line.split()
# print(line)
if line[0] == "swap" and line[1] == "position":
x, y = int(line[2]), int(line[5])
return swap(password, x, y)
if line[0] == "swap" and line[1] == "letter":
x = password.index(line[2])
y = password.index(line[5])
return swap(password, x, y)
if line[0] == "rotate" and line[1] == "right":
x = int(line[2])
return rotate_right(password, x)
if line[0] == "rotate" and line[1] == "left":
x = int(line[2])
return rotate_left(password, x)
if line[0] == "rotate" and line[1] == "based":
x = line[6]
index = "".join(password).find(x)
if index >= 0:
if index >= 4:
index += 1
rotate = (1 + index) % len(password)
return rotate_right(password, rotate)
return password
if line[0] == "reverse":
x = int(line[2])
y = int(line[4])
return password[:x] + (password[x:y+1])[::-1] + password[y+1:]
if line[0] == "move":
x = int(line[2])
y = int(line[5])
letter = password[x]
removed = password[:x] + password[x+1:]
return removed[:y] + [letter] + removed[y:]
else:
raise Exception("Cannot parse instructions in line {}".format(line))
def scramble_pass(password, input_string):
lines = input_string.split('\n')
password = list(password)
for line in lines:
password = parse_line(line, password)
return "".join(password)
def unscramble_pass(password, input_string):
lines = input_string.split('\n')[::-1]
for start in itertools.permutations(password):
if scramble_pass(start, input_string) == password:
return start
test_pass = "abcde"
test_input = """swap position 4 with position 0
swap letter d with letter b
reverse positions 0 through 4
rotate left 1 step
move position 1 to position 4
move position 3 to position 0
rotate based on position of letter b
rotate based on position of letter d"""
my_pass = "abcdefgh"
my_input = """rotate right 3 steps
swap letter b with letter a
move position 3 to position 4
swap position 0 with position 7
swap letter f with letter h
rotate based on position of letter f
rotate based on position of letter b
swap position 3 with position 0
swap position 6 with position 1
move position 4 to position 0
rotate based on position of letter d
swap letter d with letter h
reverse positions 5 through 6
rotate based on position of letter h
reverse positions 4 through 5
move position 3 to position 6
rotate based on position of letter e
rotate based on position of letter c
rotate right 2 steps
reverse positions 5 through 6
rotate right 3 steps
rotate based on position of letter b
rotate right 5 steps
swap position 5 with position 6
move position 6 to position 4
rotate left 0 steps
swap position 3 with position 5
move position 4 to position 7
reverse positions 0 through 7
rotate left 4 steps
rotate based on position of letter d
rotate left 3 steps
swap position 0 with position 7
rotate based on position of letter e
swap letter e with letter a
rotate based on position of letter c
swap position 3 with position 2
rotate based on position of letter d
reverse positions 2 through 4
rotate based on position of letter g
move position 3 to position 0
move position 3 to position 5
swap letter b with letter d
reverse positions 1 through 5
reverse positions 0 through 1
rotate based on position of letter a
reverse positions 2 through 5
swap position 1 with position 6
swap letter f with letter e
swap position 5 with position 1
rotate based on position of letter a
move position 1 to position 6
swap letter e with letter d
reverse positions 4 through 7
swap position 7 with position 5
swap letter c with letter g
swap letter e with letter g
rotate left 4 steps
swap letter c with letter a
rotate left 0 steps
swap position 0 with position 1
reverse positions 1 through 4
rotate based on position of letter d
swap position 4 with position 2
rotate right 0 steps
swap position 1 with position 0
swap letter c with letter a
swap position 7 with position 3
swap letter a with letter f
reverse positions 3 through 7
rotate right 1 step
swap letter h with letter c
move position 1 to position 3
swap position 4 with position 2
rotate based on position of letter b
reverse positions 5 through 6
move position 5 to position 3
swap letter b with letter g
rotate right 6 steps
reverse positions 6 through 7
swap position 2 with position 5
rotate based on position of letter e
swap position 1 with position 7
swap position 1 with position 5
reverse positions 2 through 7
reverse positions 5 through 7
rotate left 3 steps
rotate based on position of letter b
rotate left 3 steps
swap letter e with letter c
rotate based on position of letter a
swap letter f with letter a
swap position 0 with position 6
swap position 4 with position 7
reverse positions 0 through 5
reverse positions 3 through 5
swap letter d with letter e
move position 0 to position 7
move position 1 to position 3
reverse positions 4 through 7"""
assert scramble_pass(test_pass, test_input) == "decab"
print scramble_pass(my_pass, my_input)
x = unscramble_pass("fbgdceah", my_input)
print(x)
assert scramble_pass(x, my_input) == "fbgdceah"