22
\$\begingroup\$

An \$n\times n\$ Latin Square is a grid containing exactly \$n\$ distinct values where the values in each row and column are distinct. For example,

$$\begin{matrix} A & B & C \\ C & A & B \\ B & C & A \\ \end{matrix}$$

is a Latin square as no row or column contains a repeated value.

You are to take a positive integer \$n\$ as input and output an \$n\times n\$ Latin Square. The values can be any \$n\$ distinct values, and do not have to be consistent for different \$n\$. Your program should be consistent and deterministic, so running it with the same input should always produce the same output.

You may output in any reasonable manner, including a flat array consisting of \$n^2\$ values, or as a list of \$n\$ lists, each containing \$n\$ values. You may input and output in any convenient method

This is , so the shortest code in bytes wins.

Test cases

These are just some possible outputs, your program may differ so long as the output is correct

1 [[1]]
2 [[1, 2], [2, 1]]
3 [[1, 2, 3], [2, 3, 1], [3, 1, 2]]
4 [[1, 2, 3, 4], [2, 1, 4, 3], [3, 4, 1, 2], [4, 3, 2, 1]]
5 [[1, 2, 3, 4, 5], [2, 3, 5, 1, 4], [3, 5, 4, 2, 1], [4, 1, 2, 5, 3], [5, 4, 1, 3, 2]]
\$\endgroup\$
3
  • \$\begingroup\$ Related. Related. Brownie points for beating or matching my 12 byte Jelly answer \$\endgroup\$ Apr 15 at 20:27
  • \$\begingroup\$ It there an upper limit on n the code can assume? \$\endgroup\$
    – cnamejj
    Apr 16 at 1:01
  • 3
    \$\begingroup\$ @cnamejj Yeah, you'll never have to handle an integer greater than the square root of the maximum integer in your languages (basically, don't worry about big n so long as your algorithm is sound) \$\endgroup\$ Apr 16 at 1:10

44 Answers 44

18
+150
\$\begingroup\$

Python 2, 37 bytes

Outputs a flattened \$ n \times n \$ latin square.

lambda n:((range(n)*-~n)[1:]*n)[::~n]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Very nice! I'll post a bounty when the question becomes eligible. \$\endgroup\$
    – xnor
    Apr 16 at 4:58
  • \$\begingroup\$ @xnor Thanks, I appreciate it! \$\endgroup\$ Apr 16 at 6:17
12
\$\begingroup\$

Jelly, 3 bytes

RṙⱮ

Try it online!

Explanation

RṙⱮ  Monadic link, takes an argument z
R    [1, 2, ..., z-1, z]
  Ɱ  For each on right argument (z, defaults to loop over range)
 ṙ   Rotate the left list by the right amount

Alternative solution: +þ%. Generates the \$n\times n\$ addition table and then applies modulo to bring the elements into range.

\$\endgroup\$
7
  • 5
    \$\begingroup\$ First time I've seen caird coinheringaahing get beaten that bad. \$\endgroup\$
    – user
    Apr 15 at 20:33
  • 2
    \$\begingroup\$ rip the 12 byte answer \$\endgroup\$ Apr 15 at 20:37
  • 1
    \$\begingroup\$ The advantage of 3 byte answers is that they are easy to bruteforce. :) \$\endgroup\$ Apr 17 at 12:43
  • 2
    \$\begingroup\$ @EricDuminil I wouldn't say 16.7 million is that easy, but I guess it's all subjective, especially since it's not like there's particularly a good way to determine if a 3-byte sequence is a valid solution. \$\endgroup\$
    – hyper-neutrino
    Apr 17 at 19:28
  • 1
    \$\begingroup\$ @hyper-neutrino: Sorry, I didn't want to downplay your impressive achievement. I should have written "possible" instead of "easy". \$\endgroup\$ Apr 17 at 19:37
10
\$\begingroup\$

APL (dzaima/APL), 4 bytes

⌽ᐵ⍨⍳
⌽ rotate
ᐵ each left, apply each left element to the entire right argument
⍨ apply to both arguments
⍳ range

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Ok, that's really cool. I've not come across ᐵ before. \$\endgroup\$ Apr 17 at 6:18
  • 1
    \$\begingroup\$ @AndrewOgden yeah it's dzaima/APL specific, equivalent in regular dyalog would have to use rank (or ⊂ like bubbler's solution) \$\endgroup\$
    – rak1507
    Apr 17 at 11:50
10
\$\begingroup\$

APL (Dyalog Unicode), 6 bytes

⍳⌽,⍨⍴⍳

Try it online!

There's already a nice 4-byter in dzaima/APL by rak1507, but I wanted to share a non-trivial short one in vanilla Dyalog. It is shorter than a modulo addition table ⊢|⍳∘.+⍳ and ties with the trivial port of rak's ⍳⌽¨∘⊂⍳.

Takes n and creates a flat matrix of numbers.

⍳⌽,⍨⍴⍳   ⍝ Input: n
  ,⍨     ⍝ [n, n]
    ⍴⍳   ⍝ Reshape [1..n] into an n×n matrix
         ⍝ For n = 4, this looks like this:
         ⍝ 1 2 3 4
         ⍝ 1 2 3 4
         ⍝ 1 2 3 4
         ⍝ 1 2 3 4
⍳⌽       ⍝ Rotate first row once, second row twice, ..., n-th row n times
         ⍝ 2 3 4 1
         ⍝ 3 4 1 2
         ⍝ 4 1 2 3
         ⍝ 1 2 3 4
\$\endgroup\$
9
\$\begingroup\$

R, 30 bytes

n=scan();outer(1:n,1:n,`+`)%%n

Try it online!

\$\endgroup\$
0
7
\$\begingroup\$

Haskell, 32 bytes

f n=[[x..n]++[1..x-1]|x<-[1..n]]

Try it online!

A kind-of boring approach, just concatenates the ranges.

34 bytes

f n=[mod(k+div(-k)n)n|k<-[1..n*n]]

Try it online!

Outputs a flat list, zero-indexed, using the method from my Python answer. A slight adaptation is needing to make it work for [1..n*n] instead of [0..n*n-1].

\$\endgroup\$
5
\$\begingroup\$

Python 2, 40 bytes

lambda n:[(k+k/n)%n for k in range(n*n)]

Try it online!

Since the challenge allows a flat list of n*n outputs, we make do mapping k=0, 1, ... n*n-1 to the corresponding entry with (k+k/n)%n. We can get this by adding the row index k/n and column k%n and reducing modulo n, and removing the redundant inner %n. We could also do k*-~n/n%n.

\$\endgroup\$
5
\$\begingroup\$

Haskell, 37 35 bytes

Saved 2 bytes thanks to @Delfad0r Would have saved 5 bytes thanks to @AZTECCO (see xnor's answer)

f n=[mod(x+o)n|x<-[1..n],o<-[1..n]]

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ -2 bytes if you output a flat list. \$\endgroup\$
    – Delfad0r
    Apr 15 at 21:32
  • 2
    \$\begingroup\$ Using mod is a good idea but you can just concat two sequences around 'o' for 32 \$\endgroup\$
    – AZTECCO
    Apr 15 at 21:43
  • 1
    \$\begingroup\$ @AZTECCO Thanks! I see xnor posted the same answer (after you suggested your tip), so I think I'll go back to Delfad0r's solution so it isn't the same. \$\endgroup\$
    – user
    Apr 15 at 21:47
5
\$\begingroup\$

Retina, 22 bytes

.+
*
Y`\_`w
L$`.
$<'$`

Try it online! Explanation:

.+
*

Convert the input to unary.

Y`\_`w

Take the first n word characters (or use p for printable ASCII etc.)

L$`.
$<'$`

Create cycled rows. ($<' is the same as $&$'.)

\$\endgroup\$
5
\$\begingroup\$

J, 7 bytes

|i.+/i.

Try it online!

Creates an "addition table" of the range 0..n with itself i.+/i. and then takes the mod of each element by n |.

\$\endgroup\$
0
5
\$\begingroup\$

Julia 1.0, 19 bytes

!n=((N=1:n).+N').%n

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Python 2, 43 bytes

lambda x,r=range:[r(i,x)+r(i)for i in r(x)]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Japt -m, 3 bytes

Output as a 2D array.

WéU

Try it

Or without the -m flag:

Japt, 4 bytes

ÆZéX

Try it

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Ok I can understand the 4bytes one but the 3bytes?OMG! \$\endgroup\$
    – AZTECCO
    Apr 15 at 23:33
  • 1
    \$\begingroup\$ @AZTECCO, probably the best kept secret in Japt! \$\endgroup\$
    – Shaggy
    Apr 15 at 23:45
  • \$\begingroup\$ Realistically both are 4 bytes though, one just moves one byte into the flag. \$\endgroup\$
    – Etheryte
    Apr 16 at 12:23
  • \$\begingroup\$ @Etheryte, flags don't count towards our scores. \$\endgroup\$
    – Shaggy
    Apr 16 at 16:18
  • \$\begingroup\$ @Downvoter, what's the problem? \$\endgroup\$
    – Shaggy
    Apr 16 at 16:19
4
\$\begingroup\$

C (clang), 73 \$\cdots\$ 49 46 bytes

Saved 3 bytes thanks to dingledooper!!!

a;f(n){for(a=n*n;a;)printf("%d ",--a*~n/n%n);}

Try it online!

Inputs \$n\$ and prints the Latin Square as a flat array consisting of \$n^2\$ values.

\$\endgroup\$
2
  • \$\begingroup\$ 46 bytes by iterating backwards and using a shorter formula which outputs negatives instead. \$\endgroup\$ Apr 16 at 0:12
  • \$\begingroup\$ @dingledooper Nice one with negatives - most ingenious, thanks! :D \$\endgroup\$
    – Noodle9
    Apr 16 at 0:14
4
\$\begingroup\$

Octave, 21 bytes

@(n,x=1:n)mod(x+x',n)

Try it online!

The same thing as many other answers...

-2 bytes by Giuseppe

\$\endgroup\$
0
4
\$\begingroup\$

JavaScript (ES6), 46 bytes

n=>[...Array(n)].map((_,i,a)=>a.map(_=>i++%n))

Try it online!


JavaScript (ES6), 42 bytes

As pointed out by @tsh, returning a flatten array is shorter.

n=>[...Array(n*n)].map((_,i)=>(i/n+i)%n|0)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ use flatten matrix is shorter n=>[...Array(n*n)].map((_,i)=>(i/n+i%n)%n|0) \$\endgroup\$
    – tsh
    Apr 16 at 2:11
4
\$\begingroup\$

Arturo, 33 bytes

$[n][map 0..(n*n)-1'x[(x+x/n)%n]]

Try it on the Arturo Playground! Note: it seems that editing the code edits it for everyone, so don't do that.

\$\endgroup\$
4
\$\begingroup\$

Perl 5 -a, 34 bytes

$,=$";say$_.."@F",1..$_-1for 1..$_

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Wolfram Language (Mathematica), 23 bytes

+##&~Array~{#,#}~Mod~#&       

or (as @Roman suggested)

Plus~Array~{#,#}~Mod~#&

Try it online!

-2 bytes thanks to @att

\$\endgroup\$
2
  • \$\begingroup\$ 23 bytes \$\endgroup\$
    – att
    Apr 16 at 17:18
  • \$\begingroup\$ Plus~Array~{#,#}~Mod~#& has the same count and is less cryptic. \$\endgroup\$
    – Roman
    Apr 17 at 15:37
4
+50
\$\begingroup\$

jq, 20 bytes

range(.*.)*(1+1/.)%.

Try it online!

output is flattened

(my first jq answer)

\$\endgroup\$
3
\$\begingroup\$

Scala, 44 bytes

n=>1 to n flatMap(_=>1 to n)sliding n take n

Try it in Scastie!

This is so simple it hardly needs an explanation, but here's one anyway:

n =>                     //The input
1 to n                   //Make a range of n numbers
  flatMap(_ => 1 to n)   //Map each to the range [1, n] and flatten
                         //This creates a list of n*n numbers
  sliding n              //Take n-sized chunks and move ahead by one each time
  take n                 //Keep the first n chunks
\$\endgroup\$
3
\$\begingroup\$

Japt, 7 bytes

o £o éX

Try it

o   - [0..U)
£   - map by:
o éX    > rotate X times [0..U)
\$\endgroup\$
3
\$\begingroup\$

PowerShell, 61 bytes

param($n)(0..($n*$n-1)|%{[math]::floor($_+$_/$n)%$n})-join" "

Try it online!

\$\endgroup\$
3
\$\begingroup\$

V (vim), 38 30 bytes

"aD@aO0<ESC>V{g<C-A>V}JqqYpdw$pq@a@qdk

Try it online!

Input as a single number.

Range creating script taken from Leo's Range, Reverse, Sum answer.

-8 bytes from Leo using J.

Fixed the problem with multidigit numbers.

Explanation

"aD@aO0<ESC>V{g<C-A>V}J
"aD                          delete first line and store in register a
   @aO0<ESC>                 print 0 on a newline a times
            V{g<C-A>         convert the zeroes to a range
                    V}J      select all, join with spaces

$xqqYp2x$pq@a@qdk
$x                           remove the last space
  qq                         start macro q:
    Yp                        duplicate current line
      dw                      remove first word (number + space)
        $p                    paste at the end
          q                  end macro
           @a@q              replay macro a times
               dk            delete last two extra iterations
\$\endgroup\$
4
  • \$\begingroup\$ You can select everything and use J to join lines with spaces more efficiently Try it online! \$\endgroup\$
    – Leo
    Apr 16 at 3:33
  • \$\begingroup\$ ah, yes. I'll add it in. \$\endgroup\$
    – Razetime
    Apr 16 at 3:35
  • \$\begingroup\$ Your answer (and my golf) don't work properly for multidigit input though \$\endgroup\$
    – Leo
    Apr 16 at 3:37
  • \$\begingroup\$ lmao, I need to delete a word instead \$\endgroup\$
    – Razetime
    Apr 16 at 3:38
3
\$\begingroup\$

MATL, 3 bytes

5YL

Try it online!

          %implicit input n
5YL       % create circular matrix of size n

Equivalent to the following Octave/MATLAB code

Octave, 23 bytes

@(n)gallery('circul',n)

Try it online!

Alternately, this is equivalent to tsh's Octave answer.

MATL, 5 bytes

:&+G\

Try it online!

	% implicit input n
:	% range 1:n
&+	% add to itself transposed, with broadcast
G\	% push n and modulo n
	% implicit output
\$\endgroup\$
0
3
\$\begingroup\$

Java (JDK), 56 bytes

n->{for(int i=n*n;i-->0;)System.out.println((i/n+i)%n);}

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Python 2, 79 bytes

n=input()
f=lambda b:f(b+b[-1:]+b[-n:-1])if len(b)<n*n else b
print f(range(n))

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! Be sure to check out our Tips for golfing in Python page for ways you can golf your program. This doesn't currently output the answer with a print before the f so you should add that to your score: Try it online!. (cont). \$\endgroup\$ Apr 18 at 19:19
  • \$\begingroup\$ (cont). Alternatively, you could change it into a version that's just a function (so doesn't need the range when calling, so that you only have to count the function definition \$\endgroup\$ Apr 18 at 19:19
  • \$\begingroup\$ @cairdcoinheringaahing Edited. I had been testing in the REPL, hence the lack of a print. \$\endgroup\$
    – Faelif
    Apr 18 at 19:22
2
\$\begingroup\$

05AB1E, 4 bytes

LD._

Try it online!

LD._  # full program
  ._  # push...
L     # [1, 2, 3, ...,
      # ..., implicit input...
L     # ]...
  ._  # rotated to the left...
      # (implicit) each element in...
LD    # [1, 2, 3, ...,
      # ..., implicit input...
LD    # ]
      # implicit output
\$\endgroup\$
2
\$\begingroup\$

Ruby, 33 bytes

->n{(0..n*n-1).map{|x|(x+x/n)%n}}

Try it online!

A lambda proc returning a flat array of n*n elements.

\$\endgroup\$
2
\$\begingroup\$

Bash, 45 44 bytes

for((i=0;i<$1*$1;)){
echo $[(i/$1+i++)%$1]
}

Try it online!

-1 thanks to dingledooper

Prints flattened square, one element per line.

\$\endgroup\$
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.