পাইথন, 1281.375 1268.625 বাইট
আমরা ল্যাটিন স্কোয়ারকে একটি সময়ে "সিদ্ধান্ত" এনকোড করি, যেখানে প্রতিটি সিদ্ধান্ত এই তিনটি ফর্মের মধ্যে একটির হয়:
- কোন সংখ্যাটি সারিতে চলে যায় আমি , কলাম জে ;
- সারিতে আমি , কোন কলামে সংখ্যাটি কে যাবে ;
- কলামে জে , কোন সারিটি কে যাবে ।
প্রতিটি পদক্ষেপে, আমরা পূর্ববর্তী সিদ্ধান্তের উপর ভিত্তি করে সমস্ত যৌক্তিক সূচনাগুলি তৈরি করি, তারপরে সম্ভাব্য পছন্দগুলির সংক্ষিপ্ত সংখ্যার সাথে সিদ্ধান্তটি বেছে নেই, যার ফলে প্রতিনিধিত্ব করার জন্য বিটগুলির ক্ষুদ্রতম সংখ্যার প্রয়োজন।
পছন্দগুলি একটি সাধারণ গাণিতিক ডিকোডার দ্বারা সরবরাহ করা হয় (পছন্দগুলির সংখ্যা অনুসারে ডিভ / মোড)। তবে এটি এনকোডিংয়ে কিছু অপ্রয়োজনীয়তা ছেড়ে দেয়: যদি কে এমন স্কোয়ারে বিভক্ত হয় যেখানে সমস্ত পছন্দের সংখ্যার গুণফল এম , তবে কে + এম , কে + 2⋅ মি , কে + 3⋅ মি ,… একই স্কোয়ারে ডিকোড করুন শেষে কিছু বাকী রাজ্যের সাথে।
স্কয়ারের আকারটি স্পষ্টভাবে এনকোডিং এড়াতে আমরা এই অপ্রয়োজনীয়তার সুযোগ নিয়ে থাকি। ডিকম্প্রেসর 1 মাপের বর্গক্ষেত্রটি ডিকোড করার চেষ্টা করে শুরু হয় যখনই ডিকোডারটি বাকী রাজ্যের সাথে শেষ হয়, ফলাফলটি ছুঁড়ে ফেলে, মূল সংখ্যাটি থেকে মিটার বিয়োগ করে , আকার 1 দ্বারা বাড়িয়ে আবার চেষ্টা করে।
import numpy as np
class Latin(object):
def __init__(self, size):
self.size = size
self.possible = np.full((size, size, size), True, dtype=bool)
self.count = np.full((3, size, size), size, dtype=int)
self.chosen = np.full((3, size, size), -1, dtype=int)
def decision(self):
axis, u, v = np.unravel_index(np.where(self.chosen == -1, self.count, self.size).argmin(), self.count.shape)
if self.chosen[axis, u, v] == -1:
ws, = np.rollaxis(self.possible, axis)[:, u, v].nonzero()
return axis, u, v, list(ws)
else:
return None, None, None, None
def choose(self, axis, u, v, w):
t = [u, v]
t[axis:axis] = [w]
i, j, k = t
assert self.possible[i, j, k]
assert self.chosen[0, j, k] == self.chosen[1, i, k] == self.chosen[2, i, j] == -1
self.count[1, :, k] -= self.possible[:, j, k]
self.count[2, :, j] -= self.possible[:, j, k]
self.count[0, :, k] -= self.possible[i, :, k]
self.count[2, i, :] -= self.possible[i, :, k]
self.count[0, j, :] -= self.possible[i, j, :]
self.count[1, i, :] -= self.possible[i, j, :]
self.count[0, j, k] = self.count[1, i, k] = self.count[2, i, j] = 1
self.possible[i, j, :] = self.possible[i, :, k] = self.possible[:, j, k] = False
self.possible[i, j, k] = True
self.chosen[0, j, k] = i
self.chosen[1, i, k] = j
self.chosen[2, i, j] = k
def encode_sized(size, square):
square = np.array(square, dtype=int)
latin = Latin(size)
chosen = np.array([np.argmax(square[:, :, np.newaxis] == np.arange(size)[np.newaxis, np.newaxis, :], axis=axis) for axis in range(3)])
num, denom = 0, 1
while True:
axis, u, v, ws = latin.decision()
if axis is None:
break
w = chosen[axis, u, v]
num += ws.index(w)*denom
denom *= len(ws)
latin.choose(axis, u, v, w)
return num
def decode_sized(size, num):
latin = Latin(size)
denom = 1
while True:
axis, u, v, ws = latin.decision()
if axis is None:
break
if not ws:
return None, 0
latin.choose(axis, u, v, ws[num % len(ws)])
num //= len(ws)
denom *= len(ws)
return latin.chosen[2].tolist(), denom
def compress(square):
size = len(square)
assert size > 0
num = encode_sized(size, square)
while size > 1:
size -= 1
square, denom = decode_sized(size, num)
num += denom
return '{:b}'.format(num + 1)[1:]
def decompress(bits):
num = int('1' + bits, 2) - 1
size = 1
while True:
square, denom = decode_sized(size, num)
num -= denom
if num < 0:
return square
size += 1
total = 0
with open('latin_squares.txt') as f:
while True:
square = [list(map(int, l.split(','))) for l in iter(lambda: next(f), '\n')]
if not square:
break
bits = compress(square)
assert set(bits) <= {'0', '1'}
assert square == decompress(bits)
print('Square {}: {} bits'.format(len(square), len(bits)))
total += len(bits)
print('Total: {} bits = {} bytes'.format(total, total/8.0))
আউটপুট:
Square 1: 0 bits
Square 2: 1 bits
Square 3: 3 bits
Square 4: 8 bits
Square 5: 12 bits
Square 6: 29 bits
Square 7: 43 bits
Square 8: 66 bits
Square 9: 94 bits
Square 10: 122 bits
Square 11: 153 bits
Square 12: 198 bits
Square 13: 250 bits
Square 14: 305 bits
Square 15: 363 bits
Square 16: 436 bits
Square 17: 506 bits
Square 18: 584 bits
Square 19: 674 bits
Square 20: 763 bits
Square 21: 877 bits
Square 22: 978 bits
Square 23: 1097 bits
Square 24: 1230 bits
Square 25: 1357 bits
Total: 10149 bits = 1268.625 bytes
0
n-1