Łaciński kwadrat jest kwadratem, który nie powtórzył symboli w rzędach lub kolumnach: .
13420
21304
32041
04213
40132
I jak wie wielu graczy Sudoku, nie potrzebujesz wszystkich liczb, aby wydedukować pozostałe liczby.
Twoim zadaniem jest skompresowanie łacińskiego kwadratu do jak najmniejszej liczby bajtów. Musisz podać jeden lub dwa programy, które kompresują / dekompresują.
Różne informacje:
- Zawsze będą używane liczby
0..N-1
, gdzieN
jest długość krawędzi kwadratu, iN<=25
- Podczas dekompresji kwadrat łaciński musi być identyczny z danymi wejściowymi.
- Twój program (programy) powinien móc (de) kompresować dowolny kwadrat łaciński (w ramach maksymalnego rozmiaru kwadratu), a nie tylko te, które podałem. Wskaźniki kompresji również powinny być podobne.
- Musisz faktycznie uruchomić kompresję i dekompresor, aby uzyskać wynik (bez środowisk uruchomieniowych na końcu wszechświata)
Przypadki testowe można znaleźć na github . Twój wynik to całkowity rozmiar skompresowanych przypadków testowych.
EDYCJA: Od 20:07 7 lipca zaktualizowałem przypadki testowe (w celu rozwiązania problemu z generacją). Uruchom ponownie program w nowych przypadkach testowych. Dzięki Anders Kaseorg .
code-challenge
compression
Nathan Merrill
źródło
źródło
0
chociażn-1
:)n
różnych symboli. : POdpowiedzi:
Python,
1281.3751266825 bajtówKodujemy na łacinę jedną „decyzję” naraz, przy czym każda decyzja ma jedną z tych trzech form:
Na każdym etapie dokonujemy wszystkich logicznych wniosków na podstawie wcześniejszych decyzji, a następnie wybieramy decyzję przy użyciu jak najmniejszej liczby możliwych wyborów, które w związku z tym reprezentują najmniejszą liczbę bitów.
Wybory są zapewniane przez prosty dekoder arytmetyczny (div / mod przez liczbę wyborów). Ale to pozostawia pewną nadmiarowość w kodowaniu: jeśli k dekoduje do kwadratu, w którym iloczyn wszystkich liczb wyborów wynosił m , to k + m , k + 2⋅ m , k + 3⋅ m ,… dekoduje do tego samego kwadratu z resztkami na końcu.
Korzystamy z tej nadmiarowości, aby uniknąć jawnego kodowania wielkości kwadratu. Dekompresor rozpoczyna od próby odkodowania kwadratu o rozmiarze 1. Ilekroć dekoder kończy stan resztki, wyrzuca ten wynik, odejmuje m od pierwotnej liczby, zwiększa rozmiar o 1 i próbuje ponownie.
Wydajność:
źródło
np.stack()
. W tym przypadku można go zastąpićnp.array([…])
i zrobiłem to w bieżącej wersji.MATLAB,
3'062,52'888,125 bajtówTo podejście po prostu porzuca ostatni rząd i ostatnią kolumnę kwadratu i przekształca każdy wpis w słowa o określonej głębokości bitowej. Głębokość bitów jest wybierana minimalnie dla danego rozmiaru kwadratu. (Sugestia @KarlNapf) Te słowa są po prostu dołączane do siebie. Dekompresja jest odwrotna.
Suma dla wszystkich przypadków testowych wynosi 23'105 bitów lub 2'888,125 bajtów. (Nadal obowiązuje dla zaktualizowanych przypadków testowych, ponieważ rozmiar moich wyników zależy tylko od wielkości danych wejściowych.)
źródło
n=9..16
4 bitów wystarczy.Python 3, 10772 bity (1346,5 bajtów)
Kompresja i dekompresja połączonych przypadków testowych zajmuje 0,1 sekundy.
Sprawdź wynik w Ideone .
źródło
len(possible)
jest 1 ipossible.index(rows[i][j])
jest 0 , tak że symbol jest kodowany bez żadnych kosztów.J , 2444 bajty
Polega na wbudowanym
A.
konwertowaniu na i z permutacji liczb całkowitych [0, n) i indeksu permutacji.Kompresuj, 36 bajtów
Dane wejściowe to tablica 2d reprezentująca kwadrat łaciński. Każdy wiersz jest konwertowany na indeks permutacji, a ten indeks jest konwertowany na listę podstawowych 255 cyfr i zastępowany wartością ASCII. Każdy ciąg jest następnie łączony przy użyciu znaku ASCII w 255.
Dekompresuj, 45 bajtów
Dzieli łańcuch wejściowy na każdą wartość ASCII równą 255 i analizuje każdą grupę jako podstawowe 255 cyfr. Następnie, korzystając z liczby grup, utwórz listę liczb całkowitych [0, długość) i permutuj ją zgodnie z każdym indeksem i zwróć jako tablicę 2d.
źródło
Python,
605245213556 bajtówcompress
przyjmuje kwadrat jako ciąg wielowierszowy, podobnie jak w przykładach i zwraca ciąg binarny, podczas gdydecompress
robi odwrotnie.Usuń ostatni wiersz + kolumnę i spakuj resztę.
base64
nie wydaje się konieczneźródło
Python 3, 1955 bajtów
Jeszcze inny, który wykorzystuje wskaźniki permutacji ...
wydajność
źródło
Python3 -
3.5723581 bajtówdataCompress
pobiera listę krotek całkowitych i zwraca ciąg znaków.dateDeCompress
pobiera ciąg i zwraca listę krotek całkowitych.Krótko mówiąc, dla każdej linii program pobiera indeks permutacji linii i zapisuje go w bazie 36. Dekompresja zajmuje dużo czasu przy dużych wejściach, ale kompresja jest naprawdę szybka nawet przy dużych wejściach.
Stosowanie:
dataCompress([(2,0,1),(1,2,0),(0,1,2)])
wynik:
c|4|3|0
dataDeCompress("c|4|3|0")
wynik:
[(2, 0, 1), (1, 2, 0), (0, 1, 2)]
źródło
permutations
połączeń wlist
wywołania -permutations
zwraca generator, który leniwie generuje wszystkie permutacje, ale jeśli spróbujesz przekształcić go wlist
, chętnie generuje wszystkie permutacje, co wymaga bardzo długi czas.O(n)
czasie, a nieO(n!)
metodą brutalną polegającą na sprawdzeniu wszystkich permutacji .Java, 2310 bajtów
Konwertujemy każdy wiersz kwadratu na liczbę reprezentującą, która permutacja leksykograficzna używa liczb czynnikowych, znanych również jako system liczb czynnikowych , który jest przydatny do permutacji numeracji.
Zapisujemy kwadrat do pliku binarnego, w którym pierwszy bajt ma rozmiar kwadratu, a następnie każdy wiersz ma jeden bajt na liczbę bajtów w binarnej reprezentacji BigInteger Java, a następnie bajty tej BigInteger.
Aby odwrócić proces i zdekompresować kwadrat, odczytujemy rozmiar z powrotem, a następnie każdą BigInteger i używamy tej liczby do generowania każdego wiersza kwadratu.
Permutor jest przystosowany z klasy, którą napisałem kilka lat temu, do pracy z permutacjami:
Stosowanie:
Z kwadratem łacińskim
latin.txt
, ściśnij:I rozpakuj to:
źródło