Created
April 2, 2018 10:08
-
-
Save KaroAntonio/dc4cea3c41c26e74e075f359c1df73de to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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