Wyzwanie
Zaprojektuj algorytm kompresji specjalizujący się w kompresji labiryntów ASCII. Konieczne będzie utworzenie zarówno algorytmu kompresji, jak i algorytmu dekompresji. Twój wynik będzie oparty na rozmiarze twoich skompresowanych labiryntów.
Labirynty
Te labirynty są wykonane głównie z bohaterów (piętrach),
+
, -
, |
, oraz #
(ściany), a dokładnie jeden każda ^
(start) i $
(koniec). Mogą również zawierać litery ASCII, które liczą się jako płytki podłogowe. Na potrzeby tego wyzwania labirynty nie muszą być rozwiązywalne, a rzeczywiste znaczenie zawartości labiryntu jest nieistotne.
+
będą stosowane do komórek ściany, w których znajduje się co najmniej jedna komórka ściany sąsiadująca poziomo i co najmniej jedna komórka ściany sąsiadująca pionowo.|
będą stosowane do komórek ściany, w których znajduje się co najmniej jedna pionowo sąsiadująca komórka ściany, ale nie ma komórek sąsiadujących poziomo.-
będą stosowane do komórek ściany, w których jest co najmniej jedna komórka ściany sąsiadująca poziomo, ale nie ma komórek ściany sąsiadujących pionowo#
będzie stosowany tylko w przypadku komórek ściany, które nie są ortogonalnie sąsiadujące z innymi komórkami ściany.
Wszystkie labirynty są prostokątne, ale niekoniecznie mają regularne wyrównanie do siatki / ściany.
Labirynty do kompresji
Labirynt 1
+----+----
| o | |
| -- | o--+
| | | $
--^-+-+---
Labirynt 2
+-----+---+
| a | |
^ +-+-+ # |
| | | B |
| | | --+ |
| c | $
+-------+--
Labirynt 3
----------+-+-+-----+-+
^ | | | | |
+-- --+R # | |p| | | |
| | | | | |
+---+ +-+-+-- +-+ | | |
| m| | | | | | | |
| +-+ | | | | | --+ | |
| | | h | | | | |
| | | | | | # --+-+ |
| | | | | | S| $
+-----+-+-+-+-+---+----
Labirynt 4
+-----+---+-+---+-------^-----+
| |x | | | tsrq |
+-+-- +-- | +-- # --+---- --+
| | | | | |
| | | | | +-+-+---+ | +-- | +-+
| | | u | | | | | | | | |
| +-+ | | | | +---- +-+---+ | |
| | | | | y | w |
| | --+ | --+ +-- | +---- | | |
| | | | | | | | | |
+-- --+ +-+ | | | | +-- | +-+-+
| | | | | | | | | |
$ | --+-+ | --+-+ | +-+-+-- --+
| | | z| | | v |
+-+---+-------+---+---+-------+
Labirynt 5
++ -----------+
++- Beep|
$ ----+---+--+
+-+boop| | |
| +--- | | | ++
| | | +++
+------+-+--+ ^
Labirynt 6
+-$---------------+-+--
| | |j
| |l ---- # ---+ | |
| | | m | +--+ |
| | | +-+---- # |
| | | | | +----+ |
|o| | | | +----+ | |
| | | | -- | |
| | | | | | -+ | | |
| | | | | | | +--- | |
| | | | +- | | | | ++
+-+ |n| | | ++ +--+ |
| | -+- | | | +-
+---+ +--- | | | ^
| | --+ --+ | |
| -- | | k | | ++
| | | +--- | ++
| | | | | |
+-- -+---- | +----+--+
Labirynt 7
+---+-+-------------+-+^+-----+-------+---+-+---+-+---+-+---+
| |c| | | | c | | | | | | |c| |
+-- | | +-- +-- # | | | +-- --+ +---- +-- | +-+ | | +-+ | --+
| | | | | | | | |c| | |
| | +-- | +-+-- +-+ +-- # +- # -+-- +-- | | --+ | | | | --+C|
|c| | | | c | | |c | | | |
+-+-+---+-+-----+---------+---------+---+-------------+---+$|
Labirynt 8
------+-+-+---+-+---+-----------+---+-----+---------------+-+
^ | | | | | | | | | r | |
+-- | | | t | | +-- +----- # ---+-- +-- --+-- ----+-+ --+ | |
| | | | | | | r | | | | | |
| | | | | +-+ --+ --+-- --------+-- | ----+ --+ | | | --+ | |
| |r| | rotation | | | | | | $
+-+-+-+-----------------------------------+---+-+---+---+-+--
Labirynt 9
|$|^--+-+---+-----+-+---+-+-+---+---+-+---+-----+
| | | | | | | | | | f | | | | |
| +-+ | | # +-+ --+ +-+ | | | # | +-+ +-- | ----+
| | | | f| | | | | | f |
| |F+-+ | | | | +---+ | | | ----+-+ | | --+ --+-+
| | | | | | | | | f | | | |
| | | | +-+-+---+-- | | | +-+-+-+ +-+ +--- # -+ |
| | | | | | | | | | | | | | |
+-+-+ | +---+ --+ | +---+-+ | | --+ f | | | | --+
| | | | | | | | | |
| --+f| | | +-- --+--f--+ --+ | ----+ | +-+ +---+
| | | | | | | | | |
+---+-----+-+-----+-----+---+-+-----------+-----+
Labirynt 10
+-----+-+-----------+
| q | | q |
|Q+-+ | +-+-+-+---- |
$ | | | | | q |
+-+ | | | | | +-- +-+
| | | | | | |
| +-- +-+ |q| +-+ | |
| q| | | | |
| | | +-- | +-+ | --+
| | | | | | | |
+-+-+-+ +-+-+ +-- | |
| | | |
+--- # -+ | | +-- | |
| q | | | | ^
+-+ +-- | | +-+ | +-+
| | | | |q| | |
| +-+-+ | +-+-- | | |
| | | | | | |
| | | +-+-+-- +-+ +-+
| | | | q |
+-+-+---------+-----+
Zasady, założenia, punktacja
- Standardowe luki są zabronione
- Napisz ogólny program, a nie taki, który działa tylko dla dziesięciu przypadków testowych. Musi być w stanie obsłużyć dowolny dowolny labirynt.
- Możesz założyć, że będzie dokładnie jedno wejście i jedno wyjście. Wejścia i wyjścia zawsze będą na granicy labiryntu.
- Możesz założyć, że wszystkie dane wejściowe wykorzystują ściany zgodne z zasadami wymienionymi powyżej. Twój algorytm kompresji nie musi działać w przypadku labiryntów zawierających ściany, które naruszają te reguły.
- Labirynty wejściowe mogą, ale nie muszą być rozwiązane.
- Możesz założyć, że labirynt będzie miał nie więcej niż 100 znaków w obu kierunkach.
- Możesz założyć, że litery nie pojawią się na krawędzi labiryntu. (ponieważ tak jest w przypadku podanych przykładów)
- Twój wynik to całkowity rozmiar wszystkich skompresowanych labiryntów w bajtach (oktetach).
- Możesz użyć szesnastkowego, base64, ciągów binarnych lub dowolnego podobnego formatu jako reprezentacji dla skompresowanego labiryntu, jeśli uznasz to za wygodniejsze. Nadal powinieneś policzyć wynik w całych oktetach, zaokrąglonych w górę dla każdego labiryntu (np. 4 cyfry base64 to 3 bajty, 2 cyfry szesnastkowe to 1 bajt, 8 cyfr binarnych to 1 bajt itp.)
- Najniższy wynik wygrywa!
źródło
Odpowiedzi:
JavaScript (Node.js) , wynik =
586 541 503 492479 bajtówŚciany są przechowywane jako zakodowany przez Huffmana strumień bitów opisujących, czy funkcja predykcji zwraca prawidłowe domysły, czy nie.
Znaki specjalne są przechowywane jako( d, c ) , gdzie re to odległość od poprzedniego znaku specjalnego i do to kod ASCII.
Wypróbuj online!
Wspólny
Kompresja
Dekompresja
W jaki sposób?
Labirynt jest kodowany jako strumień bitów, który ostatecznie jest konwertowany na ciąg znaków.
nagłówek
Nagłówek składa się z:
Dane ścienne
Przechodzimy przez cały labirynt i próbujemy przewidzieć, czy następna komórka jest ścianą, czy nie, na podstawie wcześniej napotkanych komórek. Emitujemy0 jeśli mamy rację, lub 1 jeśli się mylimy
Powoduje to sekwencję bitów korekcyjnych z (miejmy nadzieję) znacznie więcej0 jest niż 1 „s. Ta sekwencja jest podzielona na skrypty i przechowywana za pomocą zakodowanych na stałe kodów Huffmana:
00
→0000
010
→0001
1001
→0010
11100
→0011
011
→0100
Aby odkodować ścianęW.n , procedura dekompresji oblicza tę samą prognozę P.n i przełącza wynik w razie potrzeby za pomocą bitu korekcji don :
Ostateczne kształty ścian są wydedukowane w sposób podobny do odpowiedzi Nicka Kennedy'ego .
Znaki specjalne
Każdy znak specjalny jest kodowany jako:
Odległość minus1 od ostatniego znaku specjalnego (ignorując ściany):
Kod znaku:
^
,$
,#
lub[a-z]
[A-O]
[P-Z]
źródło
deflate
? Na półce jest okropnie dużo!R, wynik 668 bajtów
Wykorzystuje to fakt, że charakter ściany zależy od jej otoczenia. Jako takie, znaki ścienne mogą być kodowane jako bity. Pozostałe informacje, które muszą być przechowywane, to wymiary labiryntu, pozycje początku i końca oraz pozycje innych nieściennych postaci. Ponieważ znaki nie będące ścianami są ASCII, użyłem najbardziej znaczącego bitu każdego bajtu, aby wskazać, czy po nim jest inny znak, aby niektóre słowa w labiryncie nie musiały mieć położenia każdego znaku osobno. Należy również zauważyć, że w przypadku labiryntów mniejszych lub równych 256 znaków (np. Do 16 x 16 lub równoważnych labiryntów prostokątnych) pozycje mogą być przechowywane w jednym bajcie, podczas gdy w przypadku większych labiryntów pozycje wymagają dwóch bajtów.
Funkcje użytkowe
Algorytm kompresji
Algorytm dekompresyjny
Wypróbuj online!
źródło