-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsolve.py
116 lines (92 loc) · 2.97 KB
/
solve.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
# This file handles computing actual solutions by interfacing with the C++ solver.
from subprocess import Popen, PIPE
import time
N_THREADS = 12
N_SPLITS = 2
MILLIS = 25
N_WARMUPS = 100
N_SOLS = 5
FACEID = {
'U': 0, 'D': 1, 'R': 2, 'L': 3, 'F': 4, 'B': 5
}
COUNT = {
'': 0, '2': 1, "'": 2
}
def move(s):
return 4 * FACEID[s[0]] + COUNT[s[1:]]
def translate(s):
if s == '':
return []
sol = []
splits = s.split(' ')
i = 0
while i < len(splits):
m = splits[i]
if '(' in m:
m1 = m[1:]
m2 = splits[i + 1][:-1]
sol.append((move(m1), move(m2)))
i += 1
else:
sol.append(move(m))
i += 1
return sol
# Simple Python interface to the rob-twophase CLI
class Solver:
def connect(self):
self.proc = Popen(
[
'./twophase',
'-t', str(N_THREADS), '-s', str(N_SPLITS), '-m', str(MILLIS), '-w', str(N_WARMUPS), '-c', '-n', str(N_SOLS)
],
stdin=PIPE, stdout=PIPE
)
while 'Ready!' not in self.proc.stdout.readline().decode():
pass # wait for everything to boot up
return self
def disconnect(self):
self.proc.terminate()
def __enter__(self):
return self.connect()
def __exit__(self, exception_type, exception_value, traceback):
self.disconnect()
def solve(self, facecube):
if facecube == '':
return None
self.proc.stdin.write(('solve %s\n' % facecube).encode())
self.proc.stdin.flush() # command needs to be received instantly
tmp = self.proc.stdout.readline().decode() # either time taken or an error
if 'error' in tmp:
self.proc.stdout.readline() # also need to clear "Ready!" here
return []
sols = [] # we return multiple solutions
while True:
sol = self.proc.stdout.readline().decode()
if 'Ready!' in sol:
break
sol = ' '.join(sol.split(' ')[:-1]) # delete appended solution length
sols.append(sol)
return sols
def scramble(self):
self.proc.stdin.write('scramble\n'.encode())
self.proc.stdin.flush()
# Scrambling will never fail
self.proc.stdout.readline() # facecube
self.proc.stdout.readline() # time taken
scrambles = []
while True:
scramble = self.proc.stdout.readline().decode()
if 'Ready!' in scramble:
break
scramble = ' '.join(scramble.split(' ')[:-1])
scrambles.append(scramble)
return scrambles
if __name__ == '__main__':
from control import *
import time
with Solver() as solver:
scrambles = solver.scramble()
tick = time.time()
for scramble in scrambles:
print(scramble, expected_time(optim_halfdirs(translate(scramble))))
print(time.time() - tick)