4

I am trying to write a rubix cube solver and I would like to call the same edge repeatedly to check information from it. However the position of the three dimensional area takes up a lot of space, I would like to put the positions that I use repeatedly into a variable so I can call the variable instead of rewriting the position over and over.

This is what my rubix cube looks like:

rubixCube = [
        [["G","G","Y"], ["R","B","O"], ["R","R","O"]],
        [["G","O","O"], ["O","Y","G"], ["R","B","B"]],
        [["Y","W","Y"], ["R","O","O"], ["O","W","W"]],
        [["B","B","W"], ["B","W","G"], ["G","W","R"]],
        [["B","Y","R"], ["Y","R","W"], ["G","Y","B"]], 
        [["O","G","W"], ["B","G","R"], ["Y","Y","W"]]
        ]

and this is an example of a position I call repeatly:

if(rubixCube[0][0][1] == "W"):

can I write something approximately looking like this:

position = [0][0][1]
if(rubixCube[position] == "W"):
Noah
  • 37
  • 3
  • I'm a little confused about why you're trying to do this? Do you say that writing out `rubixCube[0][0][1]` is taking up to much space? Do you mean memory? Do you mean it's making your code look messy? – Christian Dean Sep 12 '20 at 17:14

2 Answers2

5

if you use a numpy array

import numpy as np

rubixCube = np.array([
        [["G","G","Y"], ["R","B","O"], ["R","R","O"]],
        [["G","O","O"], ["O","Y","G"], ["R","B","B"]],
        [["Y","W","Y"], ["R","O","O"], ["O","W","W"]],
        [["B","B","W"], ["B","W","G"], ["G","W","R"]],
        [["B","Y","R"], ["Y","R","W"], ["G","Y","B"]],
        [["O","G","W"], ["B","G","R"], ["Y","Y","W"]]
        ])

then you can index it with a tuple

pos = (0, 0, 1)
print(rubixCude[pos])
mazore
  • 984
  • 5
  • 11
  • 1
    And this is a short, most correct and fast working solution – baldr Sep 12 '20 at 17:16
  • @alani's answer is also a good one. It avoids the need to pull in numpy as a dependency, and gives the same functionality. I think it's great to have both options demonstrated here. – CryptoFool Sep 12 '20 at 17:55
2

If you are happy to install numpy, then this would be the standard way to handle multidimensional arrays.

If you want to keep within the standard library in order to avoid the need to install additional packages, you could make an indexer class to sit on top of your existing nested list, which will allow you to get and set elements using a tuple (or list) for the position.

class NdIndexer:
    def __init__(self, arr):
        self.arr = arr

    def __getitem__(self, index):
        val = self.arr
        for i in index:
            val = val[i]
        return val

    def __setitem__(self, index, value):
        val = self.arr
        for i in index[:-1]:
            val = val[i]
        val[index[-1]] = value

You can then do:

rubixCube = [
    [["G","G","Y"], ["R","B","O"], ["R","R","O"]],
    [["G","O","O"], ["O","Y","G"], ["R","B","B"]],
    [["Y","W","Y"], ["R","O","O"], ["O","W","W"]],
    [["B","B","W"], ["B","W","G"], ["G","W","R"]],
    [["B","Y","R"], ["Y","R","W"], ["G","Y","B"]], 
    [["O","G","W"], ["B","G","R"], ["Y","Y","W"]]
]

cube = NdIndexer(rubixCube)
position = (0,0,1)

# getting
print(rubixCube[0][0][1])  # prints: G
print(cube[position])  # prints: G

# setting
cube[position] = "X"

print(rubixCube[0][0][1])  # prints: X
print(cube[position])  # prints: X
alani
  • 12,573
  • 2
  • 13
  • 23