Skip to content

Instantly share code, notes, and snippets.

@jakelevi1996
Last active November 11, 2022 22:46
Show Gist options
  • Save jakelevi1996/856ae85870de34edc5d9314677fe58df to your computer and use it in GitHub Desktop.
Save jakelevi1996/856ae85870de34edc5d9314677fe58df to your computer and use it in GitHub Desktop.
Program to solve a happy cube
class Piece:
def __init__(self, top, bottom, left, right, h=5, w=5):
self._array = np.ones([h, w], dtype=int)
self._array[ 0, :] = top
self._array[-1, :] = bottom
self._array[ :, 0] = left
self._array[ :, -1] = right
self._original_array = self._array.copy()
def reset(self):
self._array = self._original_array.copy()
def flip(self):
self._array = np.flip(self._array, axis=0)
def rotate(self):
self._array = np.rot90(self._array)
def get_array(self):
return self._array
def __repr__(self):
return "Piece(array=\n%s\n)" % self._array
class Cube:
def __init__(self, d=5, h=5, w=5):
self._shape = [d, h, w]
self.reset()
def reset(self):
self._array = np.zeros(self._shape, dtype=int)
def place_piece(self, piece, position):
if position == 0:
self._array[ 0, :, :] += piece.get_array()
if position == 1:
self._array[-1, :, :] += piece.get_array()
if position == 2:
self._array[ :, 0, :] += piece.get_array()
if position == 3:
self._array[ :, -1, :] += piece.get_array()
if position == 4:
self._array[ :, :, 0] += piece.get_array()
if position == 5:
self._array[ :, :, -1] += piece.get_array()
if np.any(self._array > 1):
is_valid = False
else:
is_valid = True
return is_valid
def __repr__(self):
return "Cube(array=\n%s\n)" % self._array
class Transform:
def __init__(self, num_rotate, flip):
self._num_rotate = num_rotate
self._flip = flip
def apply(self, piece):
if self._flip:
piece.flip()
for _ in range(self._num_rotate):
piece.rotate()
piece_list = [
Piece(
[1, 1, 0, 1, 1],
[0, 0, 1, 0, 1],
[1, 1, 0, 1, 0],
[1, 1, 0, 1, 1],
),
Piece(
[0, 1, 0, 1, 1],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[1, 1, 0, 1, 0],
),
Piece(
[0, 1, 0, 1, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 1, 0, 1, 0],
),
Piece(
[1, 1, 0, 1, 1],
[0, 0, 0, 1, 0],
[1, 0, 1, 0, 0],
[1, 0, 1, 0, 0],
),
Piece(
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 1],
[0, 0, 1, 0, 0],
[0, 0, 1, 1, 1],
),
Piece(
[1, 1, 0, 1, 0],
[0, 1, 0, 0, 0],
[1, 1, 0, 1, 0],
[0, 0, 1, 0, 0],
),
]
cube = Cube()
def find_config(cube, unused_piece_list, used_piece_list, transform_list):
for used_piece, transform in zip(used_piece_list, transform_list):
used_piece.reset()
transform.apply(used_piece)
cube.reset()
for i, piece in enumerate(used_piece_list):
is_valid = cube.place_piece(piece, i)
if not is_valid:
return False
if len(unused_piece_list) == 0:
print("Finished!\nused_piece_list = %s" % used_piece_list)
return True
for i, piece in enumerate(unused_piece_list):
for transform in [
Transform(n, f)
for n in range(4)
for f in [False, True]
]:
next_unused_piece_list = (
unused_piece_list[:i]
+ unused_piece_list[(i + 1):]
)
next_used_piece_list = used_piece_list + [piece]
next_transform_list = transform_list + [transform]
find_config(
cube,
next_unused_piece_list,
next_used_piece_list,
next_transform_list,
)
find_config(cube, piece_list[1:], [piece_list[0]], [Transform(0, False)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment