0

I am trying to fill missing fields in a 3x3 matrix (square) in order to form a magic square (row, columns both diagonals sum are the same, filled with any none repeating positive integers ). an example of such square will be like :

[_ _  _]
[_ _ 18]
[_ 28 _]

Since it doesn't follow the basic rules of the normal magic square where its integers are limited to 1-9(from 1 to n^2). , the magic constant (sum) is not equal to 15 (n(n^2+1)/2) rather it's unknown and has many possible values.

I tried a very naïve way where I generated random numbers in the empty fields with an arbitrary max of 99 then I took the whole square passed it into a function that checks if it's a valid magic square.

It basically keeps going forever till it finds the combination of numbers in the right places.

Needless to say, this solution was dumb, it keeps going for hours before it finds the answer if ever.

I also thought about doing an exhaustive number generation (basically trying every combination of numbers) till I find the right one but this faces the same issue.

So I need help figuring out an algorithm or some way to limit the range of random number generated

Samir Mughal
  • 255
  • 2
  • 7
beel
  • 15
  • 6
  • 3
    This is hardly a programming issue, but rather the math behind the problem should be solved first. – Ronald Jun 26 '20 at 10:49
  • Are 18 and 28 given values? Is one solution enough? – Ronald Jun 26 '20 at 10:56
  • yes 18 and 28 are given values and one solution is enough preferably the one which result in the minimum sum – beel Jun 26 '20 at 10:58
  • Do you have code to find a 3 x 3 magic square filled with 1..9 ? – Ronald Jun 26 '20 at 11:12
  • yes I used the same way mentioned in the question but limited the random number max to 9 so it found it rather quickly I also found another more sophisticated way of doing it here https://www.geeksforgeeks.org/magic-square/ but the algorithm used to won't work with my problem since the "Three conditions" don't hold – beel Jun 26 '20 at 11:18
  • You could simply scale the standard 3x3 magic square. Taking the square `2,7,6;9,5,1;4,3,8`, multiplying by `5`, and adding `13` gives `23,48,43;58,38,18;33,28,53`, which is just one of many possible solutions. This one has a row/column/diagonal sum of `15 * 5 + 3 * 13 = 114`. – Mark Dickinson Jun 26 '20 at 17:43
  • 2
    I’m voting to close this question because it's more about mathematics than programming: solve the maths problem first, then code up a solution. – Mark Dickinson Jun 26 '20 at 17:45

2 Answers2

2

3 by 3 magic squares are a vector space with these three basis elements:

1  1  1      0  1 -1     -1  1  0
1  1  1     -1  0  1      1  0 -1
1  1  1      1 -1  0      0 -1  1

You can introduce 3 variables a, b, c that represent the contribution from each of the 3 basis elements, and write equations for them given your partial solution.

For example, given your example grid you'll have:

a + b - c = 18
a - b - c = 28

Which immediately gives 2b = 10 or b=-5. And a-c = 23, or c=a-23.

The space of solutions looks like this:

23    2a-28 a+5
2a-18 a     18
a-5   28    2a-23

You can see each row/column/diagonal adds up to 3a.

Now you just need to find integer solutions for a and c that satisfy your positive and non-repeating constraints.

For example, a=100, b=-5, c=77 gives:

23  172 105
182 100 18
95  28  177

The minimal sum magic square with positive integer elements occurs for a=15, and the sum is 3a=45.

23   2  20
12  15  18
10  28   7

It happens that there are no repeats here. If there were, we'd simply try the next larger value of a and so on.

Paul Hankin
  • 54,811
  • 11
  • 92
  • 118
1

A possible approach is translating the given numbers to other values. A simple division is not possible, but you can translate with (N-13)/5. Then you have a partial filled in square:

- - -                                  2 7 6
- - 1   for which there is a solution  9 5 1
- 3 -                                  4 3 8

When you translate these numbers back with (N*5)+13, you obtain:

23 48 43
58 38 18    which sums up to 114 in all directions (5 * 15) + (3 * 13)
33 28 53
Ronald
  • 2,930
  • 2
  • 7
  • 18
  • 1
    I think you're suggesting turning the problem into a standard 1-9 magic square. But there's no standard 3x3 magic square with 1 and 2 in the places where the 18 and 28 are in the example. If you're not suggesting this, then please can you work through the example given in the question to show how to do this? – Paul Hankin Jun 26 '20 at 11:36
  • It seems a nice idea, but somehow something is not quite right. Indeed, this works IF and ONLY IF there is a solution for 1 and 2 in those places. The closest I believe is [3, 7, 5], [8, 6, 1], [4, 2, 9]. All sums are 15 except unfortunately the \ diagonal which is 18. – Ronald Jun 26 '20 at 11:45
  • Found it. Changed my answer. – Ronald Jun 26 '20 at 11:50
  • I think you can fix it for this particular problem by using n -> (n-13)/5 which maps 18 to 1 and 28 to 3. I don't know how generalizable this fix is though, and it doesn't give all solutions. Ah, you updated your answer with exactly this idea as I was writing the comment ;) – Paul Hankin Jun 26 '20 at 11:58
  • Yes, it does not give all solutions, that is why I asked whether one solution is enough. – Ronald Jun 26 '20 at 12:00
  • @Paul Hankin: It may also require some effort to find the correct translation, so I vote for your answer. – Ronald Jun 26 '20 at 12:06
  • There's valid grids for which this method fails. For example, if you extend the given example by also specifying "7" in the bottom-right corner, there's an unique magic square solution, but there's no way to map it onto a 1-9 magic square with a linear transformation. But I like the idea of your solution, and it's an easy method when it works. – Paul Hankin Jun 26 '20 at 12:43