Task: Random Latin squares

C: #include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


int randInt(int low, int high) {
    return (rand() % (high - low)) + low;
}


void shuffle(int *const array, const int n) {
    if (n > 1) {
        int i;
        for (i = 0; i < n - 1; i++) {
            int j = randInt(i, n);

            int t = array[i];
            array[i] = array[j];
            array[j] = t;
        }
    }
}


void printSquare(const int *const latin, const int n) {
    int i, j;
    for (i = 0; i < n; i++) {
        printf("[");
        for (j = 0; j < n; j++) {
            if (j > 0) {
                printf(", ");
            }
            printf("%d", latin[i * n + j]);
        }
        printf("]\n");
    }
    printf("\n");
}

void latinSquare(const int n) {
    int *latin, *used;
    int i, j, k;

    if (n <= 0) {
        printf("[]\n");
        return;
    }

    
    latin = (int *)malloc(n * n * sizeof(int));
    if (!latin) {
        printf("Failed to allocate memory.");
        return;
    }

    
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            latin[i * n + j] = j;
        }
    }

    
    shuffle(latin, n);

    
    for (i = 1; i < n - 1; i++) {
        bool shuffled = false;

        while (!shuffled) {
            shuffle(&latin[i * n], n);

            for (k = 0; k < i; k++) {
                for (j = 0; j < n; j++) {
                    if (latin[k * n + j] == latin[i * n + j]) {
                        goto shuffling;
                    }
                }
            }
            shuffled = true;

        shuffling: {}
        }
    }

    
    used = (int *)malloc(n * sizeof(int));
    for (j = 0; j < n; j++) {
        memset(used, 0, n * sizeof(int));
        for (i = 0; i < n - 1; i++) {
            used[latin[i * n + j]] = 1;
        }
        for (k = 0; k < n; k++) {
            if (used[k] == 0) {
                latin[(n - 1) * n + j] = k;
                break;
            }
        }
    }
    free(used);

    
    printSquare(latin, n);
    free(latin);
}

int main() {
    
    srand((unsigned int)time((time_t)0));

    latinSquare(5);
    latinSquare(5);
    latinSquare(10);

    return 0;
}







Python: from random import choice, shuffle
from copy import deepcopy

def rls(n):
    if n <= 0:
        return []
    else:
        symbols = list(range(n))
        square = _rls(symbols)
        return _shuffle_transpose_shuffle(square)


def _shuffle_transpose_shuffle(matrix):
    square = deepcopy(matrix)
    shuffle(square)
    trans = list(zip(*square))
    shuffle(trans)
    return trans


def _rls(symbols):
    n = len(symbols)
    if n == 1:
        return [symbols]
    else:
        sym = choice(symbols)
        symbols.remove(sym)
        square = _rls(symbols)
        square.append(square[0].copy())
        for i in range(n):
            square[i].insert(i, sym)
        return square

def _to_text(square):
    if square:
        width = max(len(str(sym)) for row in square for sym in row)
        txt = '\n'.join(' '.join(f"{sym:>{width}}" for sym in row)
                        for row in square)
    else:
        txt = ''
    return txt

def _check(square):
    transpose = list(zip(*square))
    assert _check_rows(square) and _check_rows(transpose), \
        "Not a Latin square"

def _check_rows(square):
    if not square:
        return True
    set_row0 = set(square[0])
    return all(len(row) == len(set(row)) and set(row) == set_row0
               for row in square)


if __name__ == '__main__':
    for i in [3, 3,  5, 5, 12]:
        square = rls(i)
        print(_to_text(square))
        _check(square)
        print()