Python
Circular Shifts
Latin Squares
Programming
Algorithms

Generating circular shifts / reduced Latin Squares in Python

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Circular shifts provide an easy way to generate cyclic Latin squares, where each symbol appears once per row and once per column. Reduced Latin squares add normalization constraints on first row and first column, which helps avoid counting equivalent forms repeatedly. This guide shows practical generation, validation, and small-order backtracking in Python.

Generate a Cyclic Latin Square with Circular Shifts

For order n, start from base row 1..n and shift by one position per row.

python
1def cyclic_latin_square(n: int) -> list[list[int]]:
2    if n <= 0:
3        raise ValueError("n must be positive")
4    return [[(r + c) % n + 1 for c in range(n)] for r in range(n)]
5
6
7def print_square(square: list[list[int]]) -> None:
8    for row in square:
9        print(" ".join(f"{v:2d}" for v in row))
10
11sq = cyclic_latin_square(5)
12print_square(sq)

This construction is deterministic and runs in O(n^2) time.

Validate Latin Property Programmatically

Always validate generated squares, especially after refactors.

python
1def is_latin(square: list[list[int]]) -> bool:
2    n = len(square)
3    target = set(range(1, n + 1))
4
5    for row in square:
6        if set(row) != target:
7            return False
8
9    for c in range(n):
10        col_values = {square[r][c] for r in range(n)}
11        if col_values != target:
12            return False
13
14    return True
15
16print(is_latin(sq))

Validation avoids subtle bugs hidden by visually plausible output.

Understand Reduced Latin Squares

A reduced Latin square requires:

  • first row equals 1..n
  • first column equals 1..n

This removes many equivalent permutations and helps canonical comparison.

python
1def is_reduced(square: list[list[int]]) -> bool:
2    n = len(square)
3    target = list(range(1, n + 1))
4    return square[0] == target and [square[r][0] for r in range(n)] == target
5
6print(is_reduced(cyclic_latin_square(4)))

Not every Latin square is reduced, but every reduced square is a Latin square.

Backtracking Generator for One Reduced Square

For small n, backtracking with fixed first row and first column is practical.

python
1def generate_one_reduced(n: int) -> list[list[int]]:
2    if n <= 0:
3        raise ValueError("n must be positive")
4
5    square = [[0] * n for _ in range(n)]
6
7    for i in range(n):
8        square[0][i] = i + 1
9        square[i][0] = i + 1
10
11    def can_place(r: int, c: int, value: int) -> bool:
12        if value in square[r]:
13            return False
14        for rr in range(n):
15            if square[rr][c] == value:
16                return False
17        return True
18
19    def solve(pos: int) -> bool:
20        if pos == n * n:
21            return True
22
23        r, c = divmod(pos, n)
24        if r == 0 or c == 0:
25            return solve(pos + 1)
26
27        for value in range(1, n + 1):
28            if can_place(r, c, value):
29                square[r][c] = value
30                if solve(pos + 1):
31                    return True
32                square[r][c] = 0
33
34        return False
35
36    if not solve(0):
37        raise RuntimeError("No reduced square found")
38
39    return square
40
41reduced = generate_one_reduced(4)
42print_square(reduced)
43print(is_latin(reduced), is_reduced(reduced))

This produces one valid reduced square and can be extended to enumerate all solutions.

Performance and Scaling Notes

Cyclic generation scales easily. Reduced enumeration grows quickly with n and needs pruning.

Useful optimizations:

  • early row and column constraint checks
  • fixed canonical first row and first column
  • avoiding expensive object allocations in inner loops

For larger orders, consider specialized combinatorial libraries or native-language implementations.

Practical Use Cases

Latin squares are used in:

  • experimental design and scheduling
  • puzzle generation
  • test-data generation for permutation constraints
  • teaching modular arithmetic and combinatorics

Cyclic squares are excellent for fast baseline cases, while reduced squares are better for structural analysis.

Common Pitfalls

  • Assuming circular shifts generate all Latin squares.
  • Counting equivalent squares repeatedly without reduction.
  • Skipping automated validation of row and column constraints.
  • Using backtracking without pruning and hitting performance walls quickly.
  • Mixing symbol domains across generated and validated squares.

Summary

  • Circular shifts generate cyclic Latin squares efficiently.
  • Reduced Latin squares fix first row and first column for canonical form.
  • Backtracking can generate reduced examples for small orders.
  • Validate every generated square with row and column checks.
  • Use cyclic generation for speed and reduced generation for structural comparison.

Course illustration
Course illustration

All Rights Reserved.