public static byte[][][] computeParityTilesFromTileCube(byte[][][] tileCube) {
    byte[][][] parityTiles = new byte[3][tileCube.length][tileCube.length];

    // tile 1
    for (int tileIdx = 0; tileIdx < tileCube.length; tileIdx++) {
      for (int row = 0; row < tileCube.length; row++) {
        byte parity = 0;
        for (int col = 0; col < tileCube.length; col++) {
          parity = (byte)((parity + tileCube[tileIdx][row][col]) & (byte)1);
        }
        parityTiles[0][row][tileIdx] = parity;
      }
    }

    // tile 2
    for (int row = 0; row < tileCube.length; row++) {
      for (int col = 0; col < tileCube.length; col++) {
        byte parity = 0;
        for (int tileIdx = 0; tileIdx < tileCube.length; tileIdx++) {
          parity = (byte)((parity + tileCube[tileIdx][row][col]) & (byte)1);
        }
        parityTiles[1][row][col] = parity;
      }
    }

    // tile 3
    for (int tileIdx = 0; tileIdx < tileCube.length; tileIdx++) {
      for (int col = 0; col < tileCube.length; col++) {
        byte parity = 0;
        for (int row = 0; row < tileCube.length; row++) {
          parity = (byte)((parity + tileCube[tileIdx][row][col]) & (byte)1);
        }
        parityTiles[2][tileIdx][col] = parity;
      }
    }

    return parityTiles;
  }