1

please can you help me with creation of function in Wolfram Mathematica for magic square. I must create function MagicSquare[n_], which output is sqare matrix of first n^2 integers, and sum of these integers in every column, every row, and on diagonals must be the same. Please help me, I try this for a days and I failed. I need this for my school assignment.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Alex
  • 11
  • 1

2 Answers2

0

Here is a simple brute-force approach. Note the check value m is the magic constant.

(Setting the random values to the array variables makes nifty use of HoldFirst.)

n = 3;

m = n (n^2 + 1)/2;

check = {0};

While[Unequal[Union[check], {m}],
  Clear[s];
  x = Table[s[i, j], {i, 1, n}, {j, 1, n}];
  d1 = Diagonal[x];
  d2 = Diagonal[Reverse[x]];
  cols = Transpose[x];
  vars = Flatten[x];
  rand = RandomSample[Range[n^2], n^2];
  MapThread[Function[{v, r}, v = r, HoldFirst], {vars, rand}];
  check = Total /@ Join[x, cols, {d1, d2}]];

MatrixForm[x]

8 3 4

1 5 9

6 7 2

Chris Degnen
  • 8,443
  • 2
  • 23
  • 40
  • Thanks a lot for this, but it only works with n=3. I need code that works for every n. I tried something like this: I created matrix matrix=Partition[Table[0,{n^2}],n] This is matrix with nxn with all zeros. And than I tried to implement rule with this Sum[matrix[[i]][[j]],{i,1,1},{i,1,n}]==(n^3+n)/2; Sum[matrix[[i]][[j]],{i,1,n},{i,1,1}]==(n^3+n)/2; But I can't implement code with these rules, only I think it is a good start. :( – Alex Feb 28 '14 at 16:56
  • @Alex - Theoretically my answer is scalable, depending upon what `n` is set to. However, it takes an unrealistically long time (or a supercomputer) to find a solution for `n > 3`. The [wiki page](http://en.wikipedia.org/wiki/Magic_square#Types_and_construction) describes the proper process to implement. – Chris Degnen Feb 28 '14 at 18:08
0

Here is another brute force approach that works for n=3 ..

 n = 3
 m = n  (n^2 + 1) /2
 Select[
     Partition[#  , n] & /@ 
        Permutations[Range[n^2]],
          (Union @(Total /@ # )) == {m} &&
          (Union @(Total /@ Transpose[#] )) == {m} &&
          Total@Diagonal[#] == m  && 
          Total@Diagonal[Reverse@#] == m & ][[1]] // MatrixForm

This has the advantage of immediately producing an out of memory error for larger n, while Chris' will run approximately forever. :)

agentp
  • 6,849
  • 2
  • 19
  • 37
  • Thanks a lot for this george, but it only works with n=3. I need code that works for every n. I tried something like this: I created matrix matrix=Partition[Table[0,{n^2}],n] This is matrix with nxn with all zeros. And than I tried to implement rule with this Sum[matrix[[i]][[j]],{i,1,1},{i,1,n}]==(n^3+n)/2; Sum[matrix[[i]][[j]],{i,1,n},{i,1,1}]==(n^3+n)/2; But I can't implement code with these rules, only I think it is a good start. :( And, of course, for n larger than 3, I get out of memory error. – Alex Feb 28 '14 at 16:59
  • You need to implement one or more of the known approaches which are outlined on that wikipedia page. – agentp Feb 28 '14 at 18:10