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()