Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

Magic Cube

5.00/5 (4 votes)
3 Feb 2015CPOL3 min read 35.9K   332  
Code to generate Magic Cubes of odd and doubly even orders

Introduction

In mathematics, a magic cube is the 3-dimensional equivalent of a magic square, that is, a number of integers arranged in a n x n x n pattern such that the sum of the numbers on each row, each column, each pillar and the four main space diagonals is equal to a single number, the so-called magic constant of the cube.

Terminology

  • Order - The value of n in n x n x n cube.
  • Magic constant - The unique sum of any row,column,pillar or triagonal. Its value is equal to n(n3+1)/2.

Extended Siamese Method for Odd Magic Cubes

Siamese method is one method to construct magic squares of odd orders. This method can be extended to 3 dimension to construct magic cubes. Assumtion is that reader has understading of the Siamese method.

We can represent any cube using index notation e.g. [1,2,3] which represents layer-1,row-2 and column-3 of the cube. The index starts from [0,0,0] and the maximum value of the index would be [n-1,n-1,n-1].

Any move will be wrapped around (like pac man or train tunnel in Matrix). -1 value is equivalent to n-1 and n is equivalent to 0.

We start with an empty cube. Steps

  1. Place number 1 in middle of the top layer [0,(n-1)/2,(n-1)/2].
  2. Let us represent current location as [l,r,c].
  3. Move to [l-1,r,c-1].
  4. If [l-1,r,c-1] is already occupied move to [l-1,r-1,c].
  5. If [l-1,r-1,c] is also occupied move to [l+1,r,c].
  6. Fill the current cell with next number and keep iterating from step #2 till all the cells are filled with numbers from 1 to n3.

Doubly Even Magic Cube

The logic to create magic cube can be extended from following magic square

1 15 14 4
12 6 7 9
8 10 11 5
13 3 2 16

The above magic square can be created in following manner.

Start filling the square from top left hand corner. If number lies in red colored box fill the number else fill with 17-number (or n2+1-number).

Let us call the red=parity 0 and blue=parity 1.

Logic to calculate parity of index [r,c] of a magic square

Java
int nBy4 = n / 4;
boolean parity = false;
if (r >= nBy4 && r < 3 * nBy4) {
	parity = true;
}
if (c >= nBy4 && c < 3 * nBy4) {
	parity = !parity;
}

On similar lines a magic cube can be constructed.

Singly Even Magic Cube

Here the logic becomes little complex and hence leaving it out of scope of this article. Medjig method can be used to construct these magic cubes. In the demo source I have also inculded code to generate magic square of any order (including singly even magic squares). Same logic can be exended to generate cubes.

The code

The code for this is very simple.

Java
public static int[][][] getMagicCube(int n) {
	if (n % 2 == 1) {
		int[][][] magicCube = new int[n][n][n];
		// layer index, row index, column index
		int l, r, c;
		l = 0;
		r = n / 2;
		c = n / 2;

		// If you want to port this code in C++
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < magicCube.length; k++) {
					magicCube[i][j][k] = 0;
				}
			}
		}

		int last = (int) Math.pow(n, 3);
		for (int i = 0; i < last; i++) {
			magicCube[l][r][c] = i + 1;
			l--;
			l = normalize(n, l);
			c--;
			c = normalize(n, c);
			if (magicCube[l][r][c] != 0) {
				r--;
				r = normalize(n, r);
				c++;
				c = normalize(n, c);
				if (magicCube[l][r][c] != 0) {
					r++;
					r = normalize(n, r);
					l += 2;
					l = normalize(n, l);
				}
			}
		}

		return magicCube;
	} else if (n % 4 == 0) {
		int[][][] magicCube = new int[n][n][n];
		int lastPlusOne = (int) Math.pow(n, 3) + 1;
		int number = 1;
		int nBy4 = n / 4;
		for (int l = 0; l < n; l++) {
			for (int r = 0; r < n; r++) {
				for (int c = 0; c < magicCube.length; c++) {
					boolean parity = false;
					if (l >= nBy4 && l < 3 * nBy4) {
						parity = true;
					}
					if (r >= nBy4 && r < 3 * nBy4) {
						parity = !parity;
					}
					if (c >= nBy4 && c < 3 * nBy4) {
						parity = !parity;
					}						
					magicCube[l][r][c] = (parity) ? lastPlusOne - number: number;
					number++;
				}
			}
		}
		return magicCube;
	}

	throw new RuntimeException(
			"Singly even magic cubes are not returned by this method.");
}

// index should be between 0 to n-1
private static int normalize(int n, int index) {
	while (index < 0) {
		index = index + n;
	}
	while (index > n - 1) {
		index = index - n;
	}
	return index;
}

This concept can be extended to cubes of higher dimensions (hyper cube). You can visit my website where you can generate a magic cube of of any given order and dimension.

Sample of cube of order 5

Generated from code

Layer 1

109 77 75 43 11
97 70 38 6 104
65 33 1 124 92
28 21 119 87 60
16 114 82 55 48

Layer 2

15 108 76 74 42
103 96 69 37 10
91 64 32 5 123
59 27 25 118 86
47 20 113 81 54

Layer 3

41 14 107 80 73
9 102 100 68 36
122 95 63 31 4
90 58 26 24 117
53 46 19 112 85

Layer 4

72 45 13 106 79
40 8 101 99 67
3 121 94 62 35
116 89 57 30 23
84 52 50 18 111

Layer 5

78 71 44 12 110
66 39 7 105 98
34 2 125 93 61
22 120 88 56 29
115 83 51 49 17

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)