पायथन, 1281.375 1268.625 बाइट्स
हम एक समय में लैटिन वर्ग एक "निर्णय" को सांकेतिक शब्दों में बदलना, जहां प्रत्येक निर्णय इन तीन रूपों में से एक है:
- पंक्ति i , कॉलम j में कौन सी संख्या जाती है ;
- पंक्ति में मैं , जो स्तंभ संख्या कश्मीर में चला जाता है,
- कॉलम j में , संख्या k किस क्रम में जाती है।
प्रत्येक चरण में, हम उन सभी तार्किक निष्कर्षों को बनाते हैं जो हम पिछले निर्णयों के आधार पर कर सकते हैं, फिर संभव विकल्पों की सबसे छोटी संख्या के साथ निर्णय लें, जो कि प्रतिनिधित्व करने के लिए छोटी संख्या में बिट्स लेते हैं।
विकल्प एक साधारण अंकगणित विकोडक (विकल्प की संख्या से div / mod) द्वारा प्रदान किए जाते हैं। लेकिन उस पत्ते एन्कोडिंग में कुछ अतिरेक: अगर कश्मीर एक वर्ग जहां सभी की उत्पाद विकल्पों की संख्या थी डीकोड मीटर , तो k + मीटर , कश्मीर + 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
:)