Duże, duże liczby

25

Próbując odegrać kilka moich odpowiedzi w golfa, musiałem pisać duże liczby całkowite w jak najmniejszej liczbie znaków.

Teraz wiem, jak to zrobić najlepiej: sprawię , że napiszesz ten program.

Wyzwanie

  • Napisz program, który po otrzymaniu dodatniej liczby całkowitej, wyprowadza program, który wypisuje go do standardowego lub równoważnego.
  • Programy wyjściowe nie muszą być w tym samym języku co twórca.
  • Dane wyjściowe muszą mieć maksymalnie 128 bajtów.
  • Możesz zaakceptować dane wejściowe ze standardowego lub równoważnego (nie wejściowego funkcji)
  • Możesz wyprowadzić wynikowy program do standardowego lub równoważnego.
  • Liczba wyjściowa musi być w systemie dziesiętnym (podstawa 10)

Punktacja

Twój wynik jest równy najmniejszej dodatniej liczbie całkowitej, której Twój program nie może zakodować.

Wpis z największą liczbą punktów wygrywa.

niebieski
źródło
Dodałem tag metagolf, ponieważ gramy w program wyjściowy.
orlp
1
@orlp Właściwie pominąłem to celowo, ponieważ metagolf to tag kryterium punktacji, który mówi „wynik jest długością twoich wyników”. Zastanawiam się nad dodaniem na ten temat meta postu, aby umożliwić również rodzaj odwrotnej punktacji (na przykład w przypadku najszybszego kodu ).
Martin Ender
1
@ MartinBüttner Wydaje mi się, że potrzebujemy meta-ograniczonego źródła :)
orlp
2
Czym różni się wyzwanie od „który język ma największy zakres liczb całkowitych” ?
nwp
5
@nwp Myślę, że źle zrozumiałeś pytanie. Pytanie dotyczy kompresji. Przydałoby się, ale nie jest konieczne używanie języka o dużym zakresie liczb całkowitych.
ziemniak

Odpowiedzi:

2

Pyton 3 → CJam (163 122 - 1) · 255/162 + 1 ≈ 1,213 x 10 270

import sys
n = int(input())
for b in range(163, 1, -1):
    s = []
    m = n
    while m:
        m, r = divmod(m - 93, b)
        if m < 0:
            break
        s.append(r + 93)
    else:
        sys.stdout.buffer.write(b'"%s"%db' % (bytes(s[::-1]), b))
        break
else:
    sys.stdout.buffer.write(b'%d' % n)

Okazuje się, że każda liczba całkowita od 1023 do (163 122 - 1) · 255/162 może być reprezentowana co najmniej w jeden sposób przez konwersję bazy b ≤ 163 z ciągu co najwyżej 122 znaków o kodach 93 do b + 92, zamiast zwykłych od 0 do b - 1. Pozwala to uniknąć kłopotliwych znaków 34 (podwójny cudzysłów) i 92 (odwrotny ukośnik) bez dodatkowego kodu wyjściowego.

Anders Kaseorg
źródło
12

Pyth, 252 111 ≈ 3,593 × 10 266

Js[
"ixL-rC1`H``N"
N
s@L-rC1`H``NjQ252
N
"252")$import sys$$sys.stdout.buffer.write(J.encode('iso-8859-1'))$

Musiałem użyć trochę składni Pythona, ponieważ Pyth printnie może drukować iso-8859-1.

Liczba zostaje zakodowana w bazie 252 i reprezentuje każdą cyfrę w tej bazie jako znak iso-8859-1. Znaki \i "będą musiały uciekać, a zatem nie są używane. Char `nie jest używany, ponieważ gra w golfa ... A dodatkowo nie jest również używany bajt zerowy, kompilator Pyth zabrania go.

Dane wyjściowe to program z narzutem 17 bajtów:

ixL-rC1`H``N""252

Oto przykładowe użycie z największą możliwą liczbą:

Stosowanie

Wyjaśnienie

programu wyjściowego.

ixL-rC1`H``N""252
    rC1`H          create the range of chars: ['\x01', '\x02', ..., '{}']
         ``N       creates a string containing the 3 chars " ' \
   -               remove strings which consists of these 3 chars
 xL         ""     determine the index of each char in "" (encoded number)
i             252  convert from base 253 to base 10
Jakube
źródło
1
Ten program nie koduje 12, ponieważ Pyth niestety czyta CR jako LF .
Anders Kaseorg,
10

CJam, 254 109 × 1,34 x 10 262

q~254b{_33>+_91>+c}%`"{_'[>-_'!>-}%254b"

Koduję liczbę w bazie 254 i reprezentuję każdą cyfrę w tej bazie jako znak ISO 8859-1, pomijam "i \. Dane wyjściowe mają narzut 19 bajtów, ""{_'[>-_'!>-}%254bwięc mogę reprezentować wszystko mniej niż 254 128–19 lub jawnie

13392914970384089616967895168962602841770234460440231501234736723328784159136966979592516521814270581662903357791625539571324435618053333498444654631269141250284088221909534717492397543057152353603090337012149759082408143603558512232742912453092885969482645766144

Jako przykład 6153501zostałby zakodowany jako

"abc"{_'[>-_'!>-}%254b

Oto program testowy, który drukuje zakodowaną liczbę całkowitą, a następnie drukuje jej długość, a następnie wykonuje ją od razu, aby pokazać jej ważność (pozwala to uniknąć kłopotów z koniecznością kopiowania znaków niedrukowalnych do nowego programu, co nie zawsze działa z tłumaczem online).

Martin Ender
źródło
8

Perl, 10 216

print"print unpack'h*',q{",(pack'h*',<>),"}"

Również kodowanie bazowe 100, nieco bardziej eleganckie. Dane wyjściowe dla 12345678:

print unpack'h*',q{!Ce‡}

Separatory {i }odpowiednio odpowiadają wartościom szesnastkowym b7i d7, które nie mogą pojawić się na wejściu, a zatem nie trzeba ich zmieniać.

Jest 20 bajtów narzutu, pozostawiając 108 do kodowania, osiągając maksymalną wartość 10 216 -1.


Perl, 10 206

print"ord=~print\$' for'",(map chr"1$_",<>=~/.{1,2}/g),"'=~/.|/g"

Proste kodowanie podstawowe 100. Dane wyjściowe dla 12345678wygląda następująco:

ord=~print$' for'p†œ²'=~/.|/g

Narzut ma 25 bajtów, pozostawiając 103 do kodowania, osiągając maksymalną wartość 10 206 -1.

primo
źródło
6

Wspólne Lisp, 36114-1 ~ 2,62 × 10 117

(lambda(x)(format t"(lambda()#36r~36r)"x))

Największa liczba to:

26211090351056720451093583540481701853293631870718869463290032123352304400278180911395999295248235620647499507894024942982768798735038336223481384090401380184000219444632784

Wystarczy użyć bazy 36. W przypadku największego wejścia wyjście o długości 128 bajtów to:

(lambda()#36rzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz)
rdzeń rdzeniowy
źródło
1

CJam, 233 114 ≈ 7,561⋅10 269

ri233b{Kms/m]_34=+c}%s`"{iKms*}%233b"

Program wyjściowy "…"{iKms*}%233bdekoduje 8-bitowe znaki ciągu do bazowych 233 cyfr za pomocą n ↦ ⌊ n ⋅ sin 20⌋ = ⌊ n ⋅ 0,913⌋. Ta transformacja bywa zaskakująca bez konieczności wprowadzania krytycznych punktów kodowych 34 (podwójny cudzysłów) i 92 (odwrotny ukośnik) jako danych wejściowych.

Anders Kaseorg
źródło