Skip to content

Instantly share code, notes, and snippets.

@KaroAntonio
Created April 2, 2018 10:08
Show Gist options
  • Save KaroAntonio/dc4cea3c41c26e74e075f359c1df73de to your computer and use it in GitHub Desktop.
Save KaroAntonio/dc4cea3c41c26e74e075f359c1df73de to your computer and use it in GitHub Desktop.
import numpy as np
# started at 12.15
# ein solver fuer das verdamntes wurfel
# so, there are only two types of blocks,
# L blocks and straight blocks
# plus end blocks
# symbols: E = end, S = straight, L = L-block
init_chain = 'ELSLLSLLLLLLLLLLLLLSLLLLLLE'
assert(len(init_chain) == 27)
# attempt recursively?
# describe the locations of the chain in a cube according to a cube notation as:
# 0 1 2
# 3 4 5
# 6 7 8
# for the first layer, and continuing
# 9 10 11
# 12 13 14
# 15 16 17
# SCRATCH THAT
# just store states as [x,y,z] tuples
def gen_empty_wurfel():
wurfel = np.arange(27)
return wurfel.reshape(3,3,3)
w_map = gen_empty_wurfel()
fail_ctr = [0]
def idx_to_xyz( idx ):
z = idx/9
y = (idx - (z*9))/3
x = ((idx - (z*9)) - y*3)
return np.array((x,y,z))
def xyz_to_idx( xyz ):
return xyz[2]*9 + xyz[1]*3 + xyz[0]
def gen_all_states():
coords = []
for i in range(3):
for j in range(3):
for k in range(3):
coords += [[i,j,k]]
return coords
def get_direct_neighbours( xyz ):
x = xyz[0]
y = xyz[1]
z = xyz[2]
nbrs = []
if x > 0: nbrs += [xyz + np.array([-1,0,0])]
if x < 2: nbrs += [xyz + np.array([1,0,0])]
if y > 0: nbrs += [xyz + np.array([0,-1,0])]
if y < 2: nbrs += [xyz + np.array([0,1,0])]
if z > 0: nbrs += [xyz + np.array([0,0,-1])]
if z < 2: nbrs += [xyz + np.array([0,0,1])]
nbrs = [xyz_to_idx(e) for e in nbrs]
return nbrs
def get_possible_next_states( chain, states ):
# given the current states, what could come next?
# return array of next state indexes
if not states:
return w_map.flatten()
if len(states) >= len(chain):
raise Exception('Too many States :O')
# get direction
# assuming there are at least two blocks placed
if len(states) >= 2:
prev = idx_to_xyz( states[-2])
curr = idx_to_xyz( states[-1])
d = np.array(curr-prev)
#print(d)
#print(states, curr)
if chain[len(states)-1] == 'E':
# assuming 'E' comes first
return get_direct_neighbours( idx_to_xyz(states[0]))
elif chain[len(states)-1] == 'L':
possibles = []
nbrs = get_direct_neighbours( curr )
if d[0] != 0: possibles = w_map[:,:,curr[0]]
if d[1] != 0: possibles = w_map[:,curr[1],:]
if d[2] != 0: possibles = w_map[curr[2],:,:]
possibles = [e for e in list(possibles.flatten()) if e not in states and e in nbrs]
return possibles
elif chain[len(states)-1] == 'S':
possible = xyz_to_idx(curr + d)
if possible > -1 and possible < 27 and possible not in states:
return [possible]
else: return []
def solve( chain, states, fail_ctr ):
if len(states) < 27:
possibles = get_possible_next_states( chain, states )
if len(possibles) == 0: fail_ctr[0] += 1
for state in possibles:
solve(chain, states[:]+[state], fail_ctr)
else:
print('SOLUTION')
print(states)
return
solve( init_chain, [], fail_ctr )
print('N fails: {}'.format(fail_ctr[0]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment