# Generate all $3\times 3$ magic squares

Though challenges involving magic squares abound on this site, none I can find so far ask the golfer to print / output all normal magic squares of a certain size. To be clear, a normal magic square of order $$\n\$$ is:

1. An $$\n\times n\$$ array of numbers.
2. Each positive integer up to and including $$\n^2\$$ appears in exactly one position in the array, and
3. Each row, column, and both main- and anti-diagonals of the array sum to the same "magic number".

Your challenge is to write the shortest program that prints all normal magic squares of order 3. There are 8 such squares. For the purposes of this challenge, the characters surrounding the output array, such as braces or brackets that accompany arrays in many languages, are allowed. For a non-optimized example in python, see here. Happy golfing!

• Welcome to Code Golf! This looks like a reasonably well-specified challenge, but for future reference, we strongly recommend using the Sandbox to get feedback on challenge ideas before posting them to the main site. Sep 1, 2021 at 13:44
• Also, your output requirement "print them, and the brackets are allowed" is unusual; I'd recommend using the site default rules about I/O, to allow (for example) submissions to return the array from a function rather than submit a full program. Sep 1, 2021 at 13:46
• Closely related (generate a magic square of a given size, rather than generate all) Sep 1, 2021 at 14:01
• I'm a bit confused by the wording. Is there any input to the code at all? The wording and title of most of the body seem to imply that we take $n$ and produce all the order $n$ magic squares, but the final bit just says order 3. Sep 1, 2021 at 14:10
• Can we output the 8 matrices without separators, like this? (The output is unambiguous because each matrix is known to have 3 rows). If not, what separators are allowed? Sep 1, 2021 at 18:18

# Python 3, 61 bytes

Outputs every magic square, each as three comma-separated rows in the form: XXX,XXX,XXX.

for c in'\zÁßİĺ':print(f'{ord(c)*1780218+275171220:,}')


Try it online!

### Explanation

There are only eight magic squares, each of which are rotations/reflections of each other. In their flattened decimal representation, they are:

276951438, 294753618, 438951276, 492357816, 618753294, 672159834, 816357492, 834159672


What's remarkable about these numbers is that they are all congruent to 1017648 (mod 1780218), meaning they can be expressed in the form x*1780218+1017648. In the code, we actually use x*1780218+275171220 as the formula instead, since it takes up less bytes to represent in our string. The number is then comma-formatted with f'{x:,}' to show the separation of the rows.

### Python 3, 61 bytes

The same method but does not contain unicode characters, is (annoyingly) the same length.

n=50863752
for c in b'~	PFP	':n-=~c*1780218;print(f'{n:,}')


Try it online!

# MATL, 15 12 bytes

4:"3tYL@X!tP


Try it online! Outputs all matrices without separation. Note that the output is unambiguous.

Alternatively, this version uses a line as separator, for 15 bytes.

### How it works

4:      % Range [1 2 3 4]
"       % For each k in that range
3tYL  %   Magic square of size 3 (gives one of the 8 possible squares)
@     %   Push k
X!    %   Rotate matrix 90 degrees k times
t     %   Duplicate
P     %   Flip vertically
% End (implicit)
% Display stack, bottom to top (implicit)

• Ahh, a magic built-in, quite literally :) Sep 1, 2021 at 17:20
• Ah builtins! I guess I didn't specify anything about using that. Sep 2, 2021 at 18:34

# Jelly, 16 bytes

“ÑṆ6Ẉ’Ds3ZU$Ƭ;U$


A niladic Link that yields a list of eight lists of lists of digits, the eight magic squares.

Try it online!

### How?

Builds one then constructs the other seven using rotations and reflections.

“ÑṆ6Ẉ’Ds3ZU$Ƭ;U$ - Link: no arguments
“ÑṆ6Ẉ’           - base 250 literal = 276951438
D          - decimal digits -> [2,7,6,9,5,1,4,3,8]
s3        - split into threes -> [[2,7,6],[9,5,1],[4,3,8]]
Ƭ    - collect up until a fixed point is found under:
$- last two links as a monad - f=rotate(current): Z - transpose - i.e. swap rows with columns U - upend - i.e. reverse each row$ - last two links as a monad - f=add_reflections(four_rotations):
U  -   upend - i.e. revese each row of each rotation
;   -   (four_rotations) concatenate (upended)


#### Alternatives

⁽Xð×3Œ?s3ZU$Ƭ;U$

“=ẹʋ‘×3D‘ZU$Ƭ;U$


# JavaScript (Node.js), 201 bytes

_=>(h=S=>S?S.flatMap(e=>h(S.filter(a=>a!=e)).map(a=>[e,...a])):[S])([1,2,3,4,5,6,7,8,9]).filter(e=>[[0,3],[0,1],[3,1],[6,1],[1,3],[2,3],[0,4],[2,2]].every(l=>e[l]+e[l+=l]+e[l+l]==15))


Try it online!

# Explanation

The integers 1 thru 9 should appear once each in the magic square, so the sum of all elements is $$\\frac{9(9+1)}{2}=45\$$ using a relatively simple formula.

Therefore, since each row forms one-third of the magic square, the sum of each row should equal 15 (and, by definition, the sums of columns and three-length diagonals must also equal 15).

The first thing my code does is that it creates all permutations of [1,2,3,4,5,6,7,8,9] (362880 of them to be exact) and checks for the ones which follow specifications. This is done using a special procedure I used in the Parker square challenge.

Rows, columns and diagonals are encoded in a format [b, i]:

• b is the starting index
• i is the number of indexes to add

The obtained subarray for such an array [b, i] would be (if the original array was l) l[b], l[b+i], l[b+i+i]. This is done using a slightly golfier method.

We check if, for each array, the corresponding sub-array (obtained via simple indexing methods) has a sum of 15.

As it turns out there are only eight magic squares of order 3. Right after writing my solution (and golfing it), I returned to this question and clicked the math.se link to find that someone had come up with a very simple formula. This notwithstanding, I am posting my answer because I think it offers a more creative approach than simple hard-coding. I am open to suggestions for reducing length.

• Welcome to Code Golf! Great answer. Sep 1, 2021 at 15:44
• @BrowncatPrograms I'm not really new to Code Golf as a matter of fact ;) I used to be RecursiveCo but I wanted to restart for some reason so I signed up again. Sep 1, 2021 at 15:46
• I posted a clarification that the challenge is indeed only for the n=3 case. I think with this constraint, very lean code can be written, and that's what I'm looking for! I expect a few dozen bytes should do it in some language. Sep 1, 2021 at 15:51
• @rajb245 Thanks for the information! Let me update my answer. Sep 1, 2021 at 15:52

# Python 3, 89 83 bytes

The 8 magic squares of order 3 are all just rotations / reflections of each other, so this stores one of them and calculates the remaining ones.

exec("x='672','159','834'"+(';*map(print,*x),print();x=[*zip(*x)][::-1]'*4)[:-6]*2)


Try it online!

A few bytes can be saved by using an uglier output format: Try it online!

Here are two programs with numpy that don't use hardcoding. The first one is quite slow, 157 bytes:

import itertools as I,numpy as N
for p in I.permutations(N.r_[1:10]):d=N.r_[p].reshape(3,3);{*d.sum(0),*d.sum(1),d.trace(),d[:,::-1].trace()}-{15}or print(d)


Try it online!

And the second one is decently fast, 175 bytes:

from numpy import*
from itertools import*
d=r_[[*permutations(r_[1:10])]].reshape(-1,3,3)
print(d[all(c_[sum(d,1),sum(d,2),trace(d,0,1,2),trace(flip(d,2),0,1,2)]==15,axis=1)])


Try it online!

# Jelly, 22 18 bytes

9Œ!i⁼ṛɗƇ5s€3§;SEƲƇ


Try it online!

The Footer simply formats the output into a nice column of grids, remove it to see the list of matrices

-4 bytes thanks to Jonathan Allan

## How it works

9Œ!i⁼ṛɗƇ5s€3§;SEƲƇ - Main link. Takes no arguments
9                  - Set the left argument to 9
Œ!                - All permutations of [1,2,3,4,5,6,7,8,9]
ɗ 5          - Group the previous 3 links into a dyad f(p, 5):
i               -   Index of 5 in p
ṛ             -   Yield 5
⁼              -   Does the index of 5 equal 5?
Ƈ           - Keep those permutations for which f(p, 5) is true
s€3       - Split each into a 3x3 matrix
ƲƇ - Keep those matrices for which the following is true:
§      -   Sums of the rows
S    -   Sums of the columns
;     -   Concatenate
E   -   Are all equal?

• Out of the squares with all the row and column sums equal those which also have their diagonal sums also equal are those with $5$ in the centre. As such you can filter these from the permutations and save four bytes like this. Still doesn't beat hardcoding one and constructing all symmetries though (currently for that I have 16). Sep 1, 2021 at 17:15
• @JonathanAllan That's a nice observation, thanks! Sep 1, 2021 at 17:20
• this approach was what i was expecting when i asked the question; i had not considered basing the algorithm on rotations/reflections of a single hardcoded literal. great answer! Sep 18, 2021 at 20:00

# R, 79787675 70 bytes

Edit: -6 bytes thanks to Dominic van Essen.

m=matrix(c(2,7,6,9,5,1,4,3,8),3)
while(print(m<-t(print(m[3:1,])))-2)1


Try it online!

Hardcodes one square and loops though its rotations, displaying also a transposition with every iteration.

Abuses the fact that while takes only the first element in a vector/matrix to check the looping condition.

• 1 byte less May 22 at 10:44
• @DominicvanEssen thanks! That's some archaeological work here ;-) May 22 at 10:55
• yes, it's nice how sometimes good old questions suddenly get dug-up to the top of the main list... And here's 5 more bytes less, I think... May 22 at 11:49

r=reverse
m=map
[id,r,m r,r.m r]<*>m(m$m((+0).read.pure).show)[[276,951,438],[294,753,618]]  Try it online! Doesn't actually bother calculating anything, just compresses a hard-coded output. There are some tactics used for compression 1. We encode each row as a base 10 number and use m((+0).read.pure).show to turn it into a list of intergers. 2. We only encode 2 of the squares and use flips to get the remaining squares. I tried also other methods • Only encoding the first two rows / columns and calculating the remainder • Encoding each starting square only as a single number and splitting it into pieces Plus some specific optimizations that only make sense with the above (e.g. multiply by 33 or 66). # 05AB1E, 25 bytes 9Lœε3ô}ʒ4.DÅ\ªsÅ/ªsÅ|ªO˜Ë  Try it online! Brute force, takes ~42 seconds to run on TIO. Attempted explanation 9Lœε3ô} # All possible 3×3 squares (1..9 permutations, chunk in 3 pieces) ʒ4.D # Filter by (Create 4 copies of the current square first to get the parts) Å\ªsÅ/ªsÅ|ª # Take the rows, cols and diagonals in a list (Through builtins and appending into one another) O˜Ë # Flattened sums are equal? Determines magic square (filter)  Or, 23 bytes if flat lists of magic squares are acceptable: 9Lœʒ3ô4.DÅ\ªsÅ/ªsÅ|ªO˜Ë  Try it online! • 20 bytes: 9Lœ3δôʒyÅ\yÅ/yø)OË: ε3ô} can be 3δô; Å| can be ø (no idea why Å| is even a builtin tbh.. maybe it vectorizes or something; but I personally haven't used it yet); ʒ4.DÅ\ªsÅ/ªsøªO˜Ë can be ʒDÅ\ªyÅ/ªyøªO˜Ë (y is the value of filters/maps/foreach loops, so no need for the duplicates + swaps), after which it can be golfed 1 byte further to ʒyÅ\yÅ/yø)OË (or alternatively ʒDø«yÅ\ªyÅ/ªOË). Sep 3, 2021 at 8:20 • Oh actually, just ʒDøyÅ\yÅ/)O˜Ë is enough for the final part, so it's 19 bytes. Sep 3, 2021 at 8:28 # Python 2, 59 bytes l="276","951","438" exec"r=zip(*l);l=r[::-1];print r,l,;"*4  Try it online! Prints the eight arrays space-separated. • Why the last comma? Without it seems to work fine for -1: Try it online!. (Is it outgolfing xnor, or was it just a spelling mistake?) Sep 2, 2021 at 15:41 • @pajonk It would make two different separators between outputs (spaces and newlines), and it's not clear to me that's allowed. – xnor Sep 2, 2021 at 17:59 • Ah, ok. I get it now. Thanks for clarification! Sep 2, 2021 at 18:12 # Ruby, 67 bytes r=259149258 " Q\x1EG\x1EQ ".bytes{|x|p (r+=x*1780218).digits 1000}  Try it online! # 05AB1E, 15 bytes •G´dI•S3ô4F=í=ø  This hard-coded approach is 4 bytes shorter than the brute-force generator approach. Try it online. Explanation: •G´dI• # Push compressed integer 276951438 S # Convert it to a list of digits: [2,7,6,9,5,1,4,3,8] 3ô # Split it into triplets to a 3x3 matrix: [[2,7,6],[9,5,1],[4,3,8]] 4F # Loop 4 times: = # Print the current matrix with trailing newline (without popping the matrix) í # Reverse each row = # Print that matrix without popping as well ø # Zip/transpose; swapping rows/columns  See this 05AB1E tip of mine (section How to compress large integers?) to understand why •G´dI• is 276951438. # Japt, 29 21 bytes Well, this is pretty damned slightly less hideous! Outputs a 3D-array. 4o!z49#ë7816ì ò3 cUmy  Test it (footer formats output into squares) 4o!z49#ë7816ì ò3\ncUmy 4o :Range [0,4) !z :For each rotate the following that many times 49#ë7816 : 492357816 ì : To digit array ò3 : Partitions of length 3 \n :Assign to variable U c :Concat Um : Map U y : Transpose  # Nibbles, 15 bytes (30 nibbles) :;./3D10'.$$.$ 1081f18e

       D10                     # get base-10 digits of
1081f18e  # data in hex: 1081f18e
# (digits are 2,7,6,9,5,1,4,3,8);
/3                         # split into chunks of 3
.                            # and iterate over this while unique:
.$# map over each group of 3 digits $# reversing them ' # and transpose the result; ; # now save these 4 magic squares : # and join them to . # each of themselves$ # reversed Using the decimal number 276951438 directly (instead of encoding it as data in hex) also comes-out at 15 bytes (:;./3p276951438'.$\$.$\), since the final argument $ of program code can be omitted & added implicitly by Nibbles. # brainfuck, 317 bytes ++++++>++>-[----->+>+>+>+>+>+>+>+>+>+>+>+<<<<<<<<<<<<]++++++++++>->++++>+++>----->++++++>++>-->----->+>>+++++>-----<<<<<<<<<<<< <[->>.>.>.>.<.<.<.<.>>>>>.>.>.>.<.<.<.<<<<<.>>>>>>>>>.>.>.>.<.<.<.<<<<<<<<<..>>>>>>>>>.>.>.>.<.<.<.<<<<<<<<<.>>>>>.>.>.>.<.<.<.<<<<<.>.>.>.>.<.<.<.<..<<[->>>+>->>>->>+>>>+>-<<<<<<<<<<<<<]>]  Score includes one unnecessary newline for "clarity." Line 1 sets the code up. Line 2 prints a vertically mirrored pair (separated by .) on three rows, then the horizontal mirrors of the first pair (Slightly odd but more user readable than some other answers!) Then, internally, the six values off the 4 5 6 diagonal are adjusted (by +/-6 each) to flip the square diagonally, and line 2 is run again to print the other four squares. Try it online! Commented code ++++++>++>- FIll cells 0 1 and 2 with 6 2 and 255 respectively for looping [----->+>+>+>+>+>+>+>+>+>+>+>+<<<<<<<<<<<<] Iterate 255/5=51 times to fill cells 3 to 14 with ASCII "2" ++++++++++> Cell 2 = 10 for linefeed ->++++>+++>----->++++++>++>-->----->+>>+++++>-----<<<<<<<<<<<< Adjust cells 3 to 14 to 276/951/438/ (cannot include period in comments so used slash instead) <[-> Iterate twice (counter in cell 1) >.>.>.>.<.<.<.<.>>>>>.>.>.>.<.<.<.<<<<<.>>>>>>>>>.>.>.>.<.<.<.<<<<<<<<<.. Output characters for 1st pair of squares (each row needs more arrows to get away from cell 2 linefeed) >>>>>>>>>.>.>.>.<.<.<.<<<<<<<<<.>>>>>.>.>.>.<.<.<.<<<<<.>.>.>.>.<.<.<.<.. Output characters for 2nd pair of squares (basically the reverse of the first) <<[->>>+>->>>->>+>>>+>-<<<<<<<<<<<<<]> Flip diagonal by ajusting the 6 values off the 4 5 6 diagonal plus or minus 6 ] And loop to output 3rd and 4th pairs of squares  # Charcoal, 21 bytes ”)‴vv»!C”Ｆ⁴«Ｆ²«Ｄ‖»⟲»⎚  Try it online! Link is to verbose version of code. Explanation: ”)‴vv»!C”  Write a compressed magic square of digits to the canvas. Ｆ⁴«Ｆ²«Ｄ‖»⟲»  Output all the rotations and reflections of the canvas. ⎚  Clear the canvas so that there's no implicit output. The squares can be padded for easier viewing at a cost of 3 bytes: ←＆!↶⸿⦃3εⅉ‽”Ｆ⁴«Ｆ²«Ｄ‖»⟲»⎚  Try it online! Link is to verbose version of code. If two columns of four squares is acceptable output, then for 17 bytes: ”←＆!↶⸿⦃3εⅉ‽”⟲Ｃ‖Ｃ¬  Try it online! Link is to verbose version of code. Explanation: ”←＆!↶⸿⦃3εⅉ‽”  Output a padded magic square. (An unpadded square would save 3 bytes, but it would make the output format unreadable.) ⟲Ｃ  Make a 90° rotated copy. ‖Ｃ¬  Make four reflected copies of each copy. (One of these is reflected both horizontally and vertically, which is equivalent to a 180° rotation. Also the horizontal and vertical reflections are simply 180° rotations of each other. This therefore produces all of the rotations and their reflections.) # Perl 5, 70 bytes map{say for/.../g,''}map$_*1780218+275171220,unpack"W*",'\zÁßİĺ'


Try it online!

Borrowed method from @dingledooper's python3 answer.

# APL (Dyalog Unicode), 47 bytes

⎕←(3 3⍴⍕)¨1↓+\50863752,1780218×1+⎕UCS'~	PFP	'


Try it online!

fast hardcoding (fork of dingledooper method)

'...' magic string

⎕UCS cast to unicode codepoints

1+ increment

...× multiply by magic

..., prepend by magic

+\ cumulative sum

1↓ decapitate

(...)¨ for each

⍕ stringify

3 3⍴ mold to 3×3 matrix

⎕← to stdout

# Haskell, 215 bytes, intractable for n>3

import Data.List
m n|let g=sum[1..n^2]divn=filter(\s->and[all((g==).sum)(m++[d])|
m<-[s,reverse.transpose$s],let d=map(\i->m!!i!!i)[0..n-1]]). map(takeWhile(>[]).map(take n).iterate(drop n))$permutations[1..n^2]


Try it online!

# Haskell, 361 bytes, intractable for n>4

import Data.List
s 0 l=[[]]
s n[]=[]
s n(a:b)=map(a:)(s(n-1)b)++s n b
m n|let g=sum[1..n^2]divn=
filter(\m->g==sum(map(\i->m!!(n-i-1)!!i)[0..n-1]))$filter(\m->g==sum(map(\i->m!!i!!i)[0..n-1]))$concatMap permutations$filter(all((g==).sum).transpose)$concatMap(sequence.map permutations)$filter(([1..n^2]==).sort.concat)$s n$filter((g==).sum)$s n[1..n^2]


Try it online!

# Haskell, 472 bytes, intractable for n>5

import Data.List
m n=let
g=sum[1..n^2]divn
t 1 _ s x l=[[x]|sum x==s]
t i 0 0 r l=map([]:)(t(i-1)n g(l++r)[])
t i j s (a:b) l|i>0&&j>0&&s>0=map(\(e:f)->(a:e):f)(t i(j-1)(s-a)b l)++t i j s b(l++[a])
t _ _ _ _ _=[]
u s[c]=[[s]|elem s c]
u s(a:b)=[e:f|e<-a,f<-u(s-e)b]
v m@([c]:_)=[transpose$m] v m=[x:y|x<-u g m,y<-v(map(\\x)m)] in filter(\m->g==sum(map(\i->m!!(n-i-1)!!i)[0..n-1])). filter(\m->g==sum(map(\i->m!!i!!i)[0..n-1])). concatMap v$t n n g[1..n^2][]


Try it online!

# MATLAB/Octave, 165163155 153 bytes

Using the magic function directly in MATLAB/Octave for a $$\3\times3\$$ magic square would only generate a single solution, not all $$\8\$$ possible solutions.

$$\\textbf{Saved 12 bytes thanks to the comment of @ceilingcat} \$$

Golfed version. Try it online!

p=perms(1:9);p(:,5)=5;for i=1:362880,if all(sum(r=reshape(p(i,:),3,3))==15&&sum(r.')==15&sum(diag(r))==15&sum(diag(rot90(r)))==15) m(:,:,end+1)=r;end end


Ungolfed version. Try it online!

p = perms([1 2 3 4 6 7 8 9]);
m = zeros(3, 3, 0);
for i=1:size(p,1)
r = [p(i,1:4),5,p(i,5:8)];
r = reshape(r,[3,3]);
if isequal(sum(r),[15 15 15]) && isequal(sum(r.'),[15 15 15]) && isequal(sum(diag(r)),15) && isequal(sum(diag(rot90(r))),15)
m = cat(3,m,r);
end
end
disp(m);