Skip to content

Instantly share code, notes, and snippets.

@Odder
Last active June 14, 2017 08:38
Show Gist options
  • Save Odder/8688ae75b44fac89389a84618edd875f to your computer and use it in GitHub Desktop.
Save Odder/8688ae75b44fac89389a84618edd875f to your computer and use it in GitHub Desktop.
Rainbow Ball solver / scrambler
import queue
import random
import math
class Rainbow:
def __init__(self):
self.allowedSwaps = [
( 1, 2, 3, 4, 5),
( 0, 5, 2,10, 6),
( 0, 1, 3, 6, 7),
( 0, 2, 4, 7, 8),
( 0, 3, 6, 8, 9),
( 0, 4, 1, 9,10),
( 1, 2,10, 7,11),
( 2, 3, 6, 8,11),
( 3, 4, 7, 9,11),
( 4, 5, 8,10,11),
( 5, 6, 9, 6,11),
( 6, 7, 8, 9,10)
]
self.scores = [
[0,1,1,1,1,1,2,2,2,2,2,3],
[1,0,1,2,2,1,1,2,3,2,1,2],
[1,1,0,1,2,2,1,1,2,3,2,2],
[1,2,1,0,1,2,2,1,1,2,3,2],
[1,2,2,1,0,1,3,2,1,1,2,2],
[1,1,2,2,1,0,2,3,2,1,1,1],
[2,1,1,2,3,2,0,1,2,2,1,1],
[2,2,1,1,2,3,1,0,1,2,2,1],
[2,3,2,1,1,2,2,1,0,1,2,1],
[2,2,3,2,1,1,2,2,1,0,1,1],
[2,1,2,3,2,1,1,2,2,1,0,1],
[3,2,2,2,2,2,1,1,1,1,1,0]
]
self.faculties = [
3991680,
3628800,
362880,
40320,
5040,
720,
120,
24,
6,
2,
1
]
self.speed = 1.5
def scoreState(self, state):
score = 0
for i in range(12):
score += self.scores[i][state[i]]
return score
def stateToHash(self, state):
hashValue = 0
for i in range(11):
hashValue += state[i] * self.faculties[i]
return hashValue
def hashToState(self, hashValue):
state = []
pieces = [i for i in range(12)]
for i in range(11):
piece = math.floor(hashValue / self.faculties[i])
hashValue = hashValue % self.faculties[i]
state += [pieces[piece]]
state += pieces[0]
return state
def solve(self, state):
q = queue.PriorityQueue(-1)
visitedStates = {}
state = list(state)
blank = state.index(0)
for move in self.allowedSwaps[state[0]]:
newState = list(state)
newState[blank], newState[move] = newState[move], newState[blank]
score = self.scoreState(newState)
visitedStates[self.stateToHash(newState)] = True
q.put((score,newState,[move]))
while not q.empty():
_,state,solution = q.get()
state = list(state)
solution = list(solution)
blank = solution[-1]
for move in self.allowedSwaps[blank]:
newState = list(state)
newState[blank], newState[move] = newState[move], newState[blank]
if self.stateToHash(newState) in visitedStates:
continue
visitedStates[self.stateToHash(newState)] = True
score = self.scoreState(newState)
if score == 0:
return solution + [move]
q.put((score + len(solution)/self.speed, newState, solution + [move]))
q.task_done()
def scramble(self, state):
return self.solve(state)[::-1]
def randomState(self):
state = [i for i in range(12)]
random.shuffle(state)
return state
def setSpeed(self, speed):
self.speed = speed
'''
Here goes the action! or in other words, example usage
'''
A = Rainbow()
for i in range(10):
state = A.randomState()
scramble = A.solve(state)
length = len(scramble)
print('State: %s\nSolution: %s[%d]\n' % (state, scramble, length))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment