62 lines
1.4 KiB
Python
62 lines
1.4 KiB
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()
|