-
Notifications
You must be signed in to change notification settings - Fork 0
/
manual_order.py
232 lines (176 loc) · 5.62 KB
/
manual_order.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
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
from rubikscubennnsolver.RubiksCube444 import RubiksCube444, solved_4x4x4
from pprint import pprint
import json
import time
"""
Manual Order
Manually determine the order of a move sequence.
This is a caveman-style investigation
into the order of different cycles.
Given a move sequence, this creates
a virtual Rubik's Cube and applies
the sequence to the cube repeatedly
until it returns to the solved state.
The smarter way to do this is to
write the move sequence as a permutation,
factor the permutation, and find the LCM
of each independent factor's length.
This gives the order of the move sequence.
"""
def count_cycles():
#sequence_test(2)
#print("Done with sequences of length 2")
#sequence_test(3)
#print("Done with sequences of length 3")
#sequence_test(4)
#print("Done with sequences of length 4")
def sequence_test(n):
from perms import algorithm_m_clean, get_rotations
results = {}
print("Sequence\t\tCross Count\tCenter Count\tTotal Count")
tsum = 0
tc = 1
captains, sequence_to_captain = algorithm_m_clean(n)
for seq in captains:
t0 = time.time()
ncycles = get_cross_cycles(seq)
results[seq] = ncycles
t1 = time.time()
tsum += t1-t0
tc += 1
print("%-16s\t%-6d\t\t%-6d\t\t%-6d"%( seq, ncycles[0], ncycles[1], ncycles[2] ))
# results dictionary:
# keys are N-move sequences
# values are number of repeat cycles/supercycles
filename = "sequence%d.json"%(n)
with open(filename,'w') as f:
json.dump(results, f, indent=4)
def sanity_check():
"""
Run a quick sanity check.
U R U' R' = 6 repetitions of sequence,
1 center cycle (of course)
L U = 105 repetitions of sequence,
105 center cycles (of course),
15 cross cycles of 105/15 = 7 inner cycles each
"""
sequences = ["U R U' R'",
"U' L'",
"L U",
"Uw L'"]
results = {}
for sequence in sequences:
#results[sequence] = get_cycles(sequence)
#results[sequence] = get_center_cycles(sequence)
results[sequence] = get_cross_cycles(sequence)
pprint(results)
def get_cycles(sequence):
"""
Given a 4x4 cube and a move sequence,
this determines the total number of
cycles needed to go from a solved state
back to a solved state.
"""
# For each sequence, start with a fresh cube.
rr = get_cube()
# Rotate this sequence an indefinite number of times,
# checking if cube is solved after each move.
moves = sequence.split(" ")
cyclecount = 0
maxcount = 10000
while True:
# Apply this sequence to the cube
for move in moves:
if(move[0]=='2'):
# need to kludge this to work for second-layer-only moves
the_move = move[1]
move1 = the_move+'w'
move2 = the_move+'\''
rr.rotate(move1)
rr.rotate(move2)
else:
# Otherwise just apply the move
rr.rotate(move)
# Increment cycle count
cyclecount += 1
# Check if solved
if(rr.solved()):
return cyclecount
if(cyclecount>maxcount):
return -1 # Tap out
def get_center_cycles(sequence):
"""
Given a 4x4 cube and a move sequence,
this determines the number of center cycles
(between which centers are solved)
and inner cycles.
"""
rr = get_cube()
moves = sequence.split(" ")
centercyclecount = 0
innercyclecount = 0
maxcount = 10000
while True:
# Apply this sequence to the cube
for move in moves:
rr.rotate(move)
# Increment cycle count
innercyclecount += 1
# Check if center solved
if(rr.centers_solved()):
centercyclecount += 1
innercyclecount = 0
# Check if solved
if(rr.solved()):
return (centercyclecount, innercyclecount)
if(centercyclecount>maxcount):
return (-1,-1) # Tap out
def get_cross_cycles(sequence):
"""
Given a 4x4 cube and a move sequence,
this determines the number of cross cycles
(between which crosses are solved),
center cycles (between which centers are solved),
and inner cycles.
"""
rr = get_cube()
moves = sequence.split(" ")
crosscyclecount = 0
centercyclecount = 0
innercyclecount = 0
maxcount = 10000
while True:
# Apply this sequence to the cube
for move in moves:
if(move[0]=='2'):
# need to kludge this to work for second-layer-only moves
the_move = move[1]
move1 = the_move+'w'
move2 = the_move+'\''
rr.rotate(move1)
rr.rotate(move2)
else:
# Otherwise just apply the move
rr.rotate(move)
# Increment cycle count
innercyclecount += 1
# Check if center solved
if(rr.centers_solved() and centercyclecount==0):
centercyclecount = innercyclecount
# Check if crosses solved
if(rr.crosses_solved() and crosscyclecount==0):
crosscyclecount = innercyclecount
# Check if solved
if(rr.solved()):
return (crosscyclecount, centercyclecount, innercyclecount)
if(crosscyclecount>maxcount):
return (-1, -1,-1) # Tap out
def get_cube():
"""
Get a 4x4 Rubiks Cube.
"""
order = 'URFDLB'
cube = RubiksCube444(solved_4x4x4, order)
return cube
if __name__=="__main__":
count_cycles()