-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2013-BIO-3.py
More file actions
174 lines (151 loc) · 5.1 KB
/
2013-BIO-3.py
File metadata and controls
174 lines (151 loc) · 5.1 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
# Unlock
import copy
from collections import deque
# TODO: EBI: This wasn't BFS - It didn't ask for shortest path; My program doesn't work (greedy not proven) but good try as works on some
# 2022-12-28 Marking (1 right, 0 wrong, * bug):
# 011110000 8/24
SIZE = 5
def letter2indexAndCase(letter):
"""Convert a letter into its 0-indexed alphabet index and boolean case=upper"""
letter = ord(letter)
if(letter < 97):
# Uppercase
return letter-65, True
else:
# Lowercase
return letter - 97, False
def indexAndCase2letter(isUppercase, index):
"""Convert a 0-indexed alphabet index and boolean case=upper into a letter"""
if isUppercase:
# Uppercase
return chr(index+65)
else:
# Lowercase
return chr(index+97)
def repr2matrix(repr:str):
"""Convert the string repr to a 1D list of states 0off/1dim/2bright"""
matrix = [0 for i in range(SIZE**2)]
for char in repr:
# matrix[]
index, bright = letter2indexAndCase(char)
if(bright):
matrix[index] = 2
else: # Dim
matrix[index] = 1
return matrix
def matrix2repr(matrix:list):
"""Convert the 1D list of states 0off/1dim/2bright to a string repr"""
repr = ""
for i in range(SIZE**2):
if(matrix[i] != 0):
# Dim = lowercase; Bright = uppercase
repr += indexAndCase2letter(matrix[i] == 2, i)
return repr
def showMatrix(matrix:list):
for i in range(0, len(matrix), SIZE):
print(matrix[i:i+SIZE])
def pressButton(i:int,nextMatrix:list):
"""Change matrix to press button at i"""
directions = [i] # deltaindex
if (i % SIZE > 0):
# Left
directions.append(i - 1)
if (i % SIZE < SIZE - 1):
# Right
directions.append(i + 1)
if (i < SIZE * (SIZE - 1)):
# Down
directions.append(i + SIZE)
if (i >= SIZE):
# Up
directions.append(i - SIZE)
for button in directions:
# print(">", button, nextMatrix[button], "vvv")
nextMatrix[button] += 1
nextMatrix[button] %= 3
# print(nextMatrix[button])
# 1. 45m
# BFS - Too slow
# def bfsPathToOff(firstMatrix:list):
# if(sum(firstMatrix) == 0): return ""
# # BFS
# q = deque([(firstMatrix, "")]) # (matrix,path)
# visited = set()
# while q:
# matrix, path = q.popleft()
# for i, nextMatrix in enumerate(nextMatrices(matrix)):
# nextButton = indexAndCase2letter(False, i)
# if (not tuple(nextMatrix) in visited and (nextButton != matrix[-1] or nextButton != matrix[-2])): # No 3 consec
# visited.add(tuple(nextMatrix))
# # print(path + nextButton, matrix2repr(nextMatrix))
# if (sum(nextMatrix) == 0): return path + nextButton
# q.append((nextMatrix, path + nextButton))
# 2. 10m
def getPathToOff(matrix:list):
""""""
path = ""
visited = set()
lastPressed = None # Can't press (/double-press) same index twice
while True:
# Greedily check all possible pressed sqs
maxToImprove = 0 # Max equal non-zero
maxIsOne = False # Max is one
maxIndex = False # Press this button
for i in range(SIZE**2):
directions = [i] # index
if (i % SIZE > 0):
# Left
directions.append(i - 1)
if (i % SIZE < SIZE - 1):
# Right
directions.append(i + 1)
if (i < SIZE * (SIZE - 1)):
# Down
directions.append(i + SIZE)
if (i >= SIZE):
# Up
directions.append(i - SIZE)
oneCount = 0
twoCount = 0
for node in directions:
if(matrix[node] == 1):
oneCount += 1
elif(matrix[node] == 2):
twoCount += 1
if i != lastPressed:
# Get max number of same non-zero sqs
if oneCount > maxToImprove and oneCount > twoCount:
maxToImprove = oneCount
maxIsOne = True
maxIndex = i
elif twoCount > maxToImprove:
maxToImprove = twoCount
maxIsOne = False
maxIndex = i
tuple_matrix = tuple(matrix)
if sum(matrix) == 0:
# Solved
return path
elif tuple_matrix in visited:
return "IMPOSSIBLE"
visited.add(tuple_matrix)
# Press/double-press best
if(maxIsOne):
# Double-press
pressButton(maxIndex,matrix)
pressButton(maxIndex, matrix)
# showMatrix(matrix)
# print()
path += (indexAndCase2letter(True, maxIndex))
else:
# Press once
pressButton(maxIndex, matrix)
# showMatrix(matrix)
# print()
path += (indexAndCase2letter(False, maxIndex))
lastPressed = maxIndex
repr = input()
# repr = "mqrsw"
matrix = repr2matrix(repr)
print(getPathToOff(matrix))
# showMatrix(matrix)