ラテン方陣
ラテン方陣を作るスクリプトを書いてみました。
コマンドは3つの引数をとります。
第1引数は、方陣の大きさ、第2、第3引数は、それぞれ、列方向、行方向の並べ替え順を示します。
並べ替え順は階乗進法で表した数とし、対応する順列が使用されます。0を指定すれば標準形が使用されます。
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys def factoradic(n): """指定された自然数nを、階乗進法で表した配列を返す ex) n = 85 ==> 85=3*4!+2*3!+0*2!+1*1! なので [3,2,0,1]を返す """ rslt = [] rslt.append(n%2) n = n - rslt[0] k = 2 while n != 0: r = n / k a = r % (k+1) rslt.append(a) n = n - a * k k = k + 1 rslt.reverse() return rslt def k_factoradic(k, n): """k桁の階乗進を表す配列を作成する""" rslt = factoradic(n) l = len(rslt) if l < k: l = ([0]*(k-l)) l.extend(rslt) return l else: return rslt[-k:] def permute(sqquence, factor): """sequenceを入替えた順列を作成する、factorは階乗進で表した並べ方を示す""" k = len(sqquence) f = k_factoradic(k-1, factor) #print sqquence, f rslt = [] for i in range(k-1): rslt.append(sqquence[f[i]]) sqquence.pop(f[i]) #print sqquence, rslt rslt.append(sqquence[0]) return rslt def latin_square(k, row_factor=None, col_factor=None): """ラテン方陣を作成する""" sq = [] row = range(1, k+1) if row_factor is not None: row = permute(row, row_factor) for i in range(k): sq.append(row) tmp = row[1:] tmp.append(row[0]) row = tmp if col_factor is not None: sq = permute(sq, col_factor) return sq def print_sq(sq): k = len(sq) for i in range(k): for j in range(k): print sq[i][j], print def main(): (k, row_factor, col_factor) = (5, None, None) argc = len(sys.argv) if argc >= 2: k = int(sys.argv[1]) if argc >= 3: row_factor = int(sys.argv[2]) if argc >= 4: col_factor = int(sys.argv[3]) print_sq(latin_square(k, row_factor, col_factor)) if __name__ == "__main__": main()