Mam na myśli konkretną liczbę, ale jest to część wyzwania, które podejmuję i nie chcę, aby ludzie wykonali (całą) pracę za mnie.
Oto liczba, która ma te same cyfry, ale jest tasowana:
5713167915926167134578399473447223554460066674314639815391281352328315313091488448321843
8892917486601064146636679920143691047671721184150386045081532202458651561779976236919751
5521854951599379666116678853267398393892536121049731949764192014193648608210652358947001
6332620900065461061195026191178967128001712341637591690941978871368243245270800684616029
6679555942849366434586090627998161441134473428845367022486230724219981658438108844675033
4461550796750244527407413996606134735852639191026103378962082622204359677030054592798927
4145951979523473408718011778751084514127053772614511042703365596651912104541233491744530
87457854312602843967491787086250478422477028164189
Liczba ma 666 cyfr (dziesiętnie). Ponieważ używam Pythona, liczby całkowite (lub technicznie długie) są automatycznie dużymi liczbami.
Mam 255 znaków do użycia i muszę opisać ten sam numer. Opis ma być uruchamiany przez eval () w celu uzyskania oryginalnego numeru.
Jakie strategie powinienem szukać?
code-golf
kolmogorov-complexity
tips
python
compression
Christian Sonne
źródło
źródło
Odpowiedzi:
Kodowanie podstawowe
Standardową techniką kompresji liczb jest wyrażanie ich w dużej bazie i kodowanie cyfr jako znaków. Np. Jeśli kodujesz numer w bazie 256, miałby on tylko 277 cyfr:
Lub wyrażone jako ciąg
(Plus niektóre niedrukowalne znaki, które są usuwane przez SE.)
Oczywiście to wciąż za długo na limit 255 znaków. Jeśli jednak mówisz o postaciach (w przeciwieństwie do bajtów), możesz przejść do Unicode i użyć znacznie większej bazy. Co powiesz na 2 16 ? To tylko 139 cyfr:
(Nie mogę tutaj podać rzeczywistego ciągu, ponieważ zawiera on pewne znaki CJK, które zostały zablokowane przez SE.)
Teraz wydaje się to bardziej wykonalne. Musisz tylko móc go zdekodować za pomocą 116 znaków. Jeśli nie możesz, Unicode ma znacznie więcej niż 2 16 znaków, więc możesz spróbować użyć jeszcze większej bazy.
źródło
Pierwsza faktoryzacja
Jeśli liczba nie ma interesujących funkcji, najlepszym sposobem jest kodowanie podstawowe. Następną rzeczą do zrobienia jest poszukiwanie interesujących cech tego numeru. Pierwszy, który przychodzi na myśl, to fakt, że może mieć czynniki małych liczb pierwszych (2,3,5,7 itd.) Podniesione do dość dużych mocy. JEŚLI nie masz już nic do roboty, staraj się dzielić na małe liczby pierwsze i zobacz, co się stanie. Jeśli jej czynniki obejmują
2**4
,3**4
i7**4
można pisaćbig number *42**4
co kilka bajtów krótszy niżbig number * 3111696
źródło
n
liczby pierwszej, możesz zapisać mniej więcej cyfrę na liczbę pierwszą, przechowując jej indeks zamiast liczby pierwszej.Rekurencyjne usuwanie największego kwadratu
Takie podejście wielokrotnie usuwa największą liczbę kwadratową z N, dopóki kontynuowanie nie będzie miało żadnej wartości.
Jeśli zignorujesz znaki „** 2 +”, ten wyniesie średnio taką samą liczbę cyfr, jak liczba oryginalna. Nadrobienie tych 4 dodatkowych znaków na iterację wymaga odrobiny szczęścia. W przypadku twojego numeru wynik ma 670 cyfr liczb kwadratowych plus 7x „** 2+”, kolejny błąd:
Algorytm, który prawie się łamie, nawet średnio, dobrze nadaje się do użycia w połączeniu z innymi algorytmami (lub nawet samymi) w celu dalszego zmniejszenia liczb w wyrażeniu (kosztem niektórych nawiasów). Te inne algorytmy mogą być droższe, ponieważ będą działać na znacznie mniejszych liczbach niż oryginał. W podanym przykładzie zysk netto mógłby zostać osiągnięty, gdyby droższy i skuteczniejszy algorytm mógł wyciąć 25% znaków
33300095205899066129442737321270515378501483166974896029394675779096351509514355500527819871697116193238261137790928953798777695127752032484956608505929119246433389165
(druga duża wartość w wyniku)źródło
W pobliżu duże mocarstwa
Podejście to szuka [względnie] małych liczb podniesionych do pewnej mocy zbliżonej do liczby docelowej. W większości przypadków przekształcenie N jako A ** B + C nie będzie poprawą, ale w niektórych przypadkach będzie.
10000
jest dowolną stałą. Warunek ratowania może również opierać się na jakimś celumindiff
.W przypadku próbki o numerze N z 666 cyframi funkcja ta (z odrobiną zwiększoną o 10k) stwierdza, że
N ~= 165661162**81.0000000025
podobnieN-165661162**81
jest z liczbą 659 cyfr, odcinając 7 cyfr od liczby, która ma być przetwarzana, kosztem 14 znaków wyrażenia , porażka.źródło