-
Notifications
You must be signed in to change notification settings - Fork 0
/
watersort.py
166 lines (136 loc) · 4.34 KB
/
watersort.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
#!python
import copy
import random
n4 = 4
level31 = ['PpgB', 'BGPb', 'ogvB', 'boop', 'prrv', 'gGoB', 'bPrg', 'GrGv', 'Pvbp', '', '']
level37 = ['GBgv', 'ggPv', 'prvo', 'GPbb', 'brBG', 'roBr', 'vbPp', 'Goop', 'BPpg', '', '']
level50 = ['ogPv', 'pppr', 'gPgb', 'vobB', 'BPbv', 'pGbB', 'gPro', 'GvGr', 'GoBr', '', '']
level52 = ['gppr', 'Bvbb', 'vvPG', 'bGBr', 'gorB', 'gGPg', 'PPor', 'oboB', 'Gpvp', '', '']
level105= ['BGbb', 'Ppgv', 'oPrd', 'opro', 'GryB', 'yGdG', 'dPrl', 'lPpl', 'gvbB', 'dyvg', 'vylB', 'gbpo', '', '']
level874= ['grbB', 'bobr', 'rlpo', 'PBgp', 'lgbl', 'BGpl', 'oGBg', 'Popr', 'PGGP', '', '']
# g grey
# r red
# b light blue
# B dark blue
# o orange
# l light green
# p pink
# P purple
# G dark green
def getParams():
global vials
#print('How many vials? >', end='')
#nVials = int(input())
nVials = -1
if nVials == -1:
vials = level874
return
vials = ['' for v in range(nVials)]
print('Enter colors of each vial as letters, starting from top-most non-empty.')
for v in range(nVials):
while True:
print('Enter vial', v, '> ', end='')
vials[v] = str(input())
if len(vials[v]) > n4:
print('Error. Length was', len(vials[v]))
else:
break
print('vials[', v, '] = "', ' ' * (n4-len(vials[v])) + vials[v], '"', sep='')
def doMove(fromV, toV, lVials):
'''Pour from vial fromV into vial toV'''
didMove = False
fromS = lVials[fromV]
toS = lVials[toV]
# print(fromS, toS)
while len(fromS) > 0 and len(toS) < n4 and (len(toS)==0 or toS[0] == fromS[0]) and fromV != toV:
toS = fromS[0] + toS
fromS = fromS[1:]
# print(fromS, toS)
didMove = True
lVials[fromV] = fromS
lVials[toV] = toS
return (didMove, lVials)
def isFinished(lVials):
'''Return true if the board is solved, else false'''
for vial in lVials:
if len(vial) == 0:
continue
if len(vial) != n4:
return False
#print(vial, lVials)
for c in vial[1:]:
#print(c, vial[0])
if c != vial[0]:
#print('bbye')
return False
return True
def printGame(game):
print('Solved it in', len(game), 'moves.')
print('init:', vials)
for fromV, toV, lVials in game:
print(fromV, '->', toV, lVials)
print()
def solveRandomly():
global vials
random.seed()
bestGame = []
while True:
lVials = copy.deepcopy(vials)
moves = 0
tries = 0
thisGame = []
#print(lVials)
while not isFinished(lVials) and tries < 5000 and moves < 60 and (moves < len(bestGame) or not bestGame):
fromV = random.randrange(len(lVials))
toV = random.randrange(len(lVials))
# print(fromV, toV)
(moved, lVials) = doMove(fromV, toV, lVials)
if moved:
moves += 1
#print(fromV, '->', toV, lVials, tries, moves)
thisGame.append((fromV, toV, copy.deepcopy(lVials)))
tries += 1
if isFinished(lVials):
print(tries, len(thisGame))
if len(thisGame) < len(bestGame) or not bestGame:
bestGame = thisGame
thisGame = []
printGame(bestGame)
#break
else:
#print("Couldn't solve it in", tries, 'tries and', moves, 'moves.')
#print('.', end='')
pass
def play():
global vials
while True:
print('\n', vials, sep='')
print('Pour from vial >', end='')
fromV = int(input())
print('Pour to vial >', end='')
toV = int(input())
(moved, vials) = doMove(fromV, toV, vials)
print('Poured.' if moved else "Didn't pour.")
if isFinished(vials):
print(vials, 'You won!')
break
def validate():
global vials
letterCnt = {}
for vial in vials:
for letter in vial:
if letter not in letterCnt:
letterCnt[letter] = 1
else:
letterCnt[letter] += 1
if not all([letterCnt[letter] == 4 for letter in letterCnt]):
print('Invalid vials:', letterCnt)
exit()
def main():
global vials
getParams()
validate()
#play()
solveRandomly()
if __name__ == '__main__':
main()