Jeśli program zakończy się i nie będzie nikogo, kto mógłby go zobaczyć, czy się zatrzyma?

99

Czas zmierzyć się z prawdą: nie będziemy tu na zawsze, ale przynajmniej możemy napisać program, który przeżyje ludzkość, nawet jeśli będzie walczyć do końca czasów.

Twoim zadaniem jest napisanie programu, którego oczekiwany czas działania jest większy niż pozostały czas do końca wszechświata.

Możesz założyć, że:

  • Wszechświat umrze od entropii za 10 1000 lat.
  • Twój komputer:
    • Przeżyje wszechświat, ponieważ jest on zbudowany z Unobtainium .
    • Ma nieograniczoną pamięć / stos / limit rekurencji.
    • Jego procesor ma ograniczoną prędkość.

Musisz pokazać, że Twój program się kończy (przepraszam, nie ma nieskończonych pętli) i obliczyć oczekiwany czas działania.

Obowiązują standardowe luki .

Jest to wyzwanie dla golfistów, więc wygrywa najkrótszy kod spełniający kryteria.

EDYCJA :

Niestety (30 minut później) stwierdzono, że nieprawdopodobne pole Unobtainium zakłóca wewnętrzny zegar komputera, czyniąc go bezużytecznym. Programy oparte na czasie natychmiast się zatrzymują. (Kto zrezygnowałby z programu, który po prostu czeka na jego żywe dziedzictwo?).

Procesor komputera jest podobny do procesora Intel i7-4578U, więc jednym ze sposobów pomiaru czasu działania jest uruchomienie programu na podobnym komputerze z mniejszym wejściem (mam nadzieję) i ekstrapolowanie jego czasu działania.


Podium

#CharsLanguageUpvotes        Author        
1    5      CJam              20       Dennis                  
2    5      J                      5         algorithmshark      
3    7      GolfScript       30       Peter Taylor          
4    9     Python             39       xnor                      
5    10   Matlab             5         SchighSchagh      

* Głosowanie na 31/08

kb_sou
źródło
40
Kusiło mnie, aby utworzyć tag [najwolniejszy kod] dla tego pytania. : P
Klamka
5
Bogosort nie działałby, ponieważ chociaż jest nieskończenie nieprawdopodobne, że nigdy się nie skończy, może wymagać nieskończonej ilości czasu, aby zakończyć. Istnieje jednak wiele okropnych wyrażeń regularnych opartych na NFA, które mogłyby spełnić kryteria „skończą się, ale nie zanim świat nie umrze”.
DavidO
49
Twoim tytułem powinna być koszulka
user-2147482637,
4
Ładne pytanie, ale czy nie powinien to być konkurs popularności?
IazertyuiopI
12
Myślę, że Izaak Asimov napisał o tym opowieść .
David Conrad,

Odpowiedzi:

34

CJam, 5 bajtów

0{)}h

Jak to działa

 0   " Push 0.                                 ";
 {   "                                         ";
   ) " Increment the Big Integer on the stack. ";
 }h  " Repeat if the value is non-zero.        ";

Ten program zostanie zatrzymany, gdy sterty nie będą już mogły przechowywać Big Integer, co nie nastąpi w najbliższym czasie na nowoczesnym komputerze stacjonarnym.

Domyślny rozmiar sterty to 4 179 623 936 bajtów na moim komputerze (Java 8 w Fedorze). Można go zwiększyć do dowolnej wartości za pomocą -Xmx, więc jedynym prawdziwym ograniczeniem jest dostępna pamięć główna.

Czas zgonu

Zakładając, że interpreter potrzebuje x bitów pamięci do przechowywania nieujemnej liczby całkowitej mniejszej niż 2 x , musimy policzyć do 2 8 × 4 179 623 936 = 2 33 436 991 488 . Z jednym przyrostem na cykl zegara i moim Core i7-3770 (3,9 GHz z turbo), zajmie to 23,436,991,488 ÷ 3 400 000 000> 10 10 065 537 373 sekund, czyli ponad 10 10 065 533 3785 lat.

Dennis
źródło
14
Nie sądzę, że możesz polegać na ograniczonych zasobach, ponieważ pytanie brzmi: „Twój komputer ma nieskończony limit pamięci / stosu / rekurencji”.
Greg Hewgill
4
Nieskończona pamięć !=nieskończone typy danych. Jeśli mam terabajt pamięci RAM, 8-bitowa liczba całkowita bez znaku wciąż rośnie do 255.
wchargin
6
@GregHewgill: Przy nieograniczonych zasobach możesz zwiększyć maksymalną wielkość sterty Java do dowolnej dowolnej wartości, ale zawsze będzie ona skończona.
Dennis,
2
@Dennis, ale po prostu dodawaj wiersz za każdym razem przez pętlę, aby podwoić rozmiar sterty. Zabawne jest to w nieskończonościach :-)
Carl Witthoft,
9
@CarlWitthoft: Nie możesz tego zrobić w programie.
Dennis,
62

JavaScript, 39

(function f(x){for(;x!=++x;)f(x+1)})(0)

Wyjaśnienie

Ponieważ JavaScript nie reprezentuje dokładnie dużych liczb całkowitych, pętla for(;x!=++x;)kończy się po xtrafieniu 9007199254740992.

Ciało pętli for będzie wykonywane Fib(9007199254740992) - 1razy, gdzie Fib(n)jest n-ta liczba Fibonacciego.

Z testów wiem, że mój komputer wykona mniej niż 150 000 iteracji na sekundę. W rzeczywistości działałby znacznie wolniej, ponieważ stos byłby bardzo duży.

Dlatego uruchomienie programu zajmie co najmniej (Fib(9007199254740992) - 1) / 150000sekundy. Nie byłem w stanie obliczyć, Fib(9007199254740992)ponieważ jest tak duży, ale wiem, że jest znacznie większy niż 10 1000 * 150 000.

EDYCJA: Jak zauważono w komentarzach, Fib(9007199254740992)jest to około 4,4092 * 10 1882393317509686 , co jest rzeczywiście wystarczająco duże.

Peter Olson
źródło
9
Ponieważ fib(n)można to przybliżyć phi^n, możemy użyć log((sqrt(5) + 1)/2)*9007199254740992do obliczenia, o ile cyfr się fib(9007199254740992)okaże 1.8823933*10^15.
overactor
11
@overactor, Według Wolfram Alpha, Fib(9007199254740992)(przy użyciu ciągłej postaci z phi) jest w przybliżeniu 4.4092... * 10^1882393317509686. Obliczenia
Brian S,
1
rosnący stos nie zmniejsza szybkości procesora ... chyba że weźmie się pod uwagę ograniczoną szerokość linii adresu pamięci / nieograniczoną szerokość adresu (w takim przypadku spowolnienie ma nadal długość adresu liniowego przy założeniu rozsądnego kodowania) lub nawet fizyczne ograniczenia pamięci i prędkość światła (w którym to przypadku spowolnienie ma wartość adresową przy założeniu przechowywania przestrzennego; nawet poziomy gęstości danych DNA ostatecznie zaczynają się sumować, nawet jeśli zarządzasz przypadkowym dostępem zajmującym mało miejsca)
John Dvorak
1
@JamesKhoury Nie, właśnie napisana funkcja jest równoważna for(x=0;x!=++x;)i iteruje tylko 9007199254740992 razy.
Peter Olson,
4
@SylvainLeroux architektura z nieskończoną ilością pamięci RAM prawdopodobnie po prostu przeplata stertę i stos i spowoduje, że oba będą rosły w górę.
John Dvorak
47

Python (9)

9**9**1e9

Ma ponad 10 ** 10000000 bitów, więc obliczenia powinny zabrać nas daleko w przeszłość po śmierci z powodu upałów.

Sprawdziłem, że dla coraz większych, ale wciąż rozsądnych wartości zajmuje to coraz więcej czasu, więc nie jest to tylko optymalizacja przez tłumacza.

Edycja: Gra w golfa dwa znaki, usuwając parens dzięki @ user2357112. TIL, że Python traktuje kolejne wykładniki jako wieżę mocy.

xnor
źródło
4
OverflowError: (34, „Wynik za duży”)
apple16
93
@ apple16 Może na twoim komputerze, ale mój ma „nieskończony limit pamięci / stosu / rekurencji”.
xnor
64
W porządku, chłopaki. Uruchomiłem go w ostatnim wszechświecie i dostałem ...82528057365719799011536835265979955007740933949599830498796942400000000009(pominięto 2,6 * 10 ^ 954242509 cyfr, aby uniknąć upadku czarnej dziury ). Naprawdę powinieneś uaktualnić do Unobtanium.
xnor
10
Potęgowanie jest prawostronne, więc możesz upuścić nawiasy.
user2357112,
10
Warto zauważyć, że 9**9**9e9jest tak samo krótki i wymaga nieco więcej długości wszechświata, a także wygląda trochę ładniej.
abarnert
35

GolfScript ( 12 7 znaków)

9,{\?}*

To oblicza i drukuje 8 ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ~ = 10 ^ 10 ^ 10 ^ 10 ^ 183230. Aby go wydrukować (nie wspominając o obliczeniach) za 10 ^ 1000 lat ~ = 10 ^ 1007,5 sekund, trzeba wydrukować około 10 ^ (10 ^ 10 ^ 10 ^ 183230 - 10 ^ 3) cyfr na sekundę.

Peter Taylor
źródło
22
Ale zatrzyma się na długo przed komunikatem „brak papieru w drukarce” ...
Floris,
1
@Floris, kto do diabła używa obecnie fizycznych mediów?
John Dvorak,
3
@JanDvorak, właśnie założyłem, że Floris i 7 osób, które go poparły, pochodzą z pokolenia mojego dziadka, kiedy cała produkcja była ciągła.
Peter Taylor
2
@PeterTaylor - może nie do końca tak stary, ale jestem na tyle stary, aby przypomnieć sobie przesyłanie „zadań wsadowych” do „komputera” (w czasach, gdy nie było wątpliwości, w populacji studentów o wielkości 20 tys., Który komputer miał na myśli), i odbiór wydruku następnego dnia. Ty (i 7 innych osób) słusznie przypuszczałeś, że była to próba humoru, a nie poważna krytyka twojego doskonałego i absurdalnie krótkiego scenariusza.
Floris,
35

Cudowne 68 66 bajtów

}0
--@2
@2/\=0MB
}0@1\/
&0/\>0!!
--
@1
00@0
--/\=0
\\@0&0

Marbelous to 8-bitowy język z wartościami reprezentowanymi tylko przez kulki w maszynie podobnej do Rube Goldberg, więc nie było to bardzo łatwe. To podejście jest w przybliżeniu równoważne z następującym pseudokodem:

function recursiveFunction(int i)
{
    for(int j = i*512; j > 0; j--)
    {
        recursiveFunction(i - 1);
    }
}

ponieważ maksymalna wartość to 256 (reprezentowana przez 0 w programie Marbleous, który jest obsługiwany w różnych miejscach w różny sposób) funkcja rekurencyjna (1) zostanie nazwana w sumie 256!*512^256równą około 10^1200, wystarczająco łatwo, aby przeżyć wszechświat.

Marbelous nie ma bardzo szybkiego interpretera, wygląda na to, że może obsługiwać 10^11wywołania tej funkcji rocznie, co oznacza, że ​​patrzymy na środowisko wykonawcze 10^1189lat.

Dalsze objaśnienie tablicy Marbelous

00@0
--/\=0
\\@0&0

00jest dosłownym językiem (lub marmurem), reprezentowanym w systemie szesnastkowym (więc 0). Ten marmur spada na --, który zmniejsza każdy marmur o 1 (00 owija się i zamienia w FF lub 255 w systemie dziesiętnym). Marmur o wartości FF spada teraz na ten, \\który przesuwa go o jedną kolumnę w prawo, na niższy @0. To jest portal i teleportuje marmur do drugiego @0urządzenia. Tam marmur ląduje na /\urządzeniu, które jest powielaczem, umieszcza jedną kopię marmuru po --lewej stronie (ten marmur będzie się ciągle pętli między portalami i ulegał zmniejszeniu w każdej pętli), a drugi po =0prawej stronie.=0porównuje marmur do wartości zero i pozwala, aby marmur spadł, jeśli jest równy, i popchnie go w prawo, jeśli nie. Jeśli marmur ma wartość 0, wyląduje na &0synchonizerze, który wyjaśnię później.

Podsumowując, zaczyna się to od marmuru o wartości 0 w pętli i zmniejsza go, aż osiągnie ponownie 0, następnie umieszcza ten marmur o wartości 0 w synchronizatorze i kontynuuje zapętlanie w tym samym czasie.

}0@1
&0/\>0!!
--
@1

}0jest urządzeniem wejściowym, początkowo n-te (podstawa 0) wejście wiersza poleceń podczas wywoływania programu jest umieszczane w każdym }nurządzeniu. Więc jeśli wywołasz ten program z wejściem wiersza poleceń 2, marmur o wartości 02 zastąpi to }0. Ten marmur następnie wpada do &0urządzenia, inny synchronizator, &nsynchronizatory trzymają kulki, aż wszystkie inne odpowiednie również &nzostaną złożone. Marmur jest następnie zmniejszany, teleportowany i duplikowany podobnie jak w poprzednio wyjaśnionej pętli. Odpowiednia kopia jest następnie sprawdzana pod kątem nierówności z wartością zero ( >0), jeśli nie jest równa 0, to przechodzi. Jeśli wynosi 0, zostaje popchnięty w prawo i ląduje !!, co kończy planszę.

Okay, do tej pory mamy pętlę, która odlicza w sposób ciągły od 255 do 0 i pozwala kolejnej, podobnej pętli (zasilanej przez dane z wiersza poleceń) uruchomić raz za każdym razem, gdy osiągnie 0. Kiedy ta druga pętla uruchomi się n razy (maksymalnie 256 ) program kończy się. To jest maksymalnie 65536 przebiegów pętli. Niewystarczająco, by przeżyć wszechświat.

}0
--@2
@2/\=0MB

Powinno to zacząć wyglądać znajomo, dane wejściowe są zmniejszane raz, a następnie ta wartość zapętla się i jest kopiowana (zauważ, że marmur zmniejsza się tylko raz, a nie przy każdym uruchomieniu pętli). Następnie jest sprawdzany pod kątem równości do 0 i jeśli nie jest to zero, ląduje dalej MB. Jest to funkcja w Marbelous, każdy plik może zawierać kilka tablic, a każda tablica jest funkcją, każda funkcja musi zostać nazwana przez poprzedzenie siatki :[name]. Każda funkcja z wyjątkiem pierwszej funkcji w pliku, która ma standardową nazwę: MB. Więc ta pętla ciągle wywołuje ponownie płytę główną z wartością, n - 1gdzie n jest wartością, z którą wywołano to wystąpienie funkcji.

Więc dlaczego n*512?

Cóż, pierwsza pętla działa z 4 tyknięciami (i 256 razy), a druga pętla biegnie n razy przed zakończeniem płytki. Oznacza to, że tablica działa na około n*4*256tyknięcia. Ostatnia pętla (która wywołuje funkcję rekurencyjną) jest złożona i działa z 2 tikami, co oznacza, że ​​udaje się wywołać n*4*256/2 = n*512czasy funkcji .

O jakich symbolach nie wspomniałeś?

\/ to kosz na śmieci, który usuwa kulki z planszy, dzięki czemu rozrzucone kulki nie kolidują z innymi kulkami, które zapętlają rundę i uniemożliwiają zakończenie programu.

Premia

Ponieważ kulki, które spadają z dolnej części cudownej płyty, są wysyłane do STDOUT, ten program wypisuje mnóstwo znaków ASCII podczas działania.

overactor
źródło
2
Świetne wyjaśnienie, dzięki!
Beta Decay
2
Wow, to świetny pomysł! Cudowny język jest świetną zabawą!
rubik
2
+1 Właśnie to, co chciałem zobaczyć. Bardziej szalony język niż BrainFuck :) Czy jest strona internetowa z samouczkiem i więcej informacji na ten temat? (Wydaje się, że link do tytułu ma mniej dokumentów niż twoja odpowiedź)
Sylwester
2
@Sylwester, cieszę się, że ci się podoba, Marbelous jest obecnie w fazie rozwoju, ale spodziewamy się, że będzie w bardziej stabilnym stanie w najbliższej przyszłości, w którym to momencie samouczki, obszerniejsza dokumentacja, standardowe biblioteki i mam nadzieję, że tłumacz online śledzić.
overactor
21

Perl, 66 58 znaków

sub A{($m,$n)=@_;$m?A($m-1,$n?A($m,$n-1):1):$n+1;}A(9,9);

Powyżej jest implementacją funkcji Ackermann – Péter . Nie mam pojęcia, jak duże jest A (9,9), ale jestem całkiem pewien, że ocena zajmie zadziwiająco dużo czasu.

Greg Hewgill
źródło
5
+1 ... Próbowałem znaleźć język z wbudowaną funkcją Ackermann, ale nie udało mi się tego, zanim skończyła się moja cierpliwość. : D
Martin Ender
3
$n?A($m-1,A($m,$n-1)):A($m-1,1)pozwala na łatwą oszczędność 8 znaków poprzez wciśnięcie operatora trójskładnikowego.
Peter Taylor
3
Jestem prawie pewien, że liczba cyfr w A (9,9) jest większa niż objętość obserwowalnego wszechświata mierzona w sześciennych długościach Plancka.
kasperd
6
@kasperd To dość masowe niedopowiedzenie. Objętość obserwowalnego wszechświata jest rzędu zaledwie 10 ^ 184 objętości Plancka. Dla porównania w liczbie opisującej liczbę cyfr w A (4,4) jest około 10 ^ 19700 cyfr, co z kolei jest niezrozumiale małe w porównaniu z A (9,9).
user19057,
3
@ user19057 To brzmi jak nazywanie roszczenia Kasperda „masywnym niedopowiedzeniem” jest masowym niedopowiedzeniem. : P
Nicu Stiurca,
20

MATLAB, 58 52 znaków

Potrzebujemy co najmniej jednego rozwiązania arytmetycznego o skończonej precyzji, stąd:

y=ones(1,999);while y*y',y=mod(y+1,primes(7910));end

x = jedynki (1,999); y = x; podczas gdy dowolne (y), y = mod (y + x, liczby pierwsze (7910)); koniec

( dzięki dzięki @DennisJaheruddin za strącenie 6 znaków )

Liczba cykli potrzebnych do ukończenia wynika z iloczynu pierwszych 999 liczb pierwszych. Ponieważ ogromna większość z nich ma znacznie ponad 10 lat, czas potrzebny do osiągnięcia konwergencji byłby o setki lub tysiące rzędów wielkości większy niż minimalny termin.

COTO
źródło
+1 Zajęło mi trochę czasu, aby zobaczyć, co tam robisz. Miły!
Naprawiono punkt
+1 CRT, prawda?
flawr
Fajnie, myślę, że niektóre znaki można zapisać w następujący sposób: y = jedynki (1,999); podczas gdy y * y ', y = mod (y + 1, liczby pierwsze (7910)); koniec
Dennis Jaheruddin
@DennisJaheruddin: Genialne skracanie. Zaktualizuję.
COTO,
Chociaż nie jest to już to samo rozwiązanie, powinno być jeszcze wystarczająco podobne i znowu nieco krótsze:p=1:9e9;y=p;while+y*y',y=mod(y+1,p),end
Dennis Jaheruddin
19

Mathematica, 25 19 bajtów

To rozwiązanie zostało opublikowane, zanim funkcje czasowe zostały zdyskwalifikowane.

While[TimeUsed[]<10^10^5]

TimeUsed[]zwraca sekundy od rozpoczęcia sesji, a Mathematica używa typów o dowolnej dokładności. W ciągu roku jest około 10 7 sekund, więc odczekanie 10 10000 sekund powinno wystarczyć.

Krótsza / prostsza (/ ważna) alternatywa:

For[i=0,++i<9^9^9,]

Zamiast tego policzmy. Będziemy musieli liczyć nieco dalej, ponieważ możemy wykonać sporo przyrostów w ciągu sekundy, ale wyższy limit nie kosztuje postaci.

Technicznie w obu rozwiązaniach mogłem zastosować znacznie niższy limit, ponieważ problem nie określa minimalnej szybkości procesora.

Martin Ender
źródło
Kocham to! Ta odpowiedź wywołała u mnie śmiech z wielkim uśmiechem na twarzy.
Todd Lehman
1
Przepraszam, ze względu na kreatywność, musiałem wyciąć rozwiązania oparte na czasie (takie jak twoje pierwsze). Proszę, nie nienawidź mnie. :)
kb_sou
5
@kbsou Cóż, pobiłem go z innym, więc tak naprawdę mnie to nie obchodzi. Ale w przeciwnym razie dyskwalifikujące odpowiedzi z mocą wsteczną za zmiany zasad nie są fajne. ;)
Martin Ender
1
Czy Mathematica jest naprawdę tak wolna, że ​​przetwarzanie danych 9^9^9trwa dłużej niż 10^1000lata? Szacuję, że obliczenia 9^9^9na moim 1.3GHz U7300 przy użyciu bczajmie mniej niż 6 miesięcy. (Na podstawie ekstrapolacji czasu obliczania 9^200000i 9^400000.)
kasperd
2
@ArtOfCode Mathematica używa typów o dowolnej dokładności, więc faktycznie spróbuje ustalić poprawną wartość.
Martin Ender,
16

Python 3 - 49

Robi to coś pożytecznego: oblicza Pi z niespotykaną dokładnością za pomocą nieskończonej serii Gregory-Leibniz.

Na wypadek, gdybyś się zastanawiał, ten program zapętla 10**10**10**2.004302604952323czasy.

sum([4/(i*2+1)*-1**i for i in range(1e99**1e99)])

Arbitralna precyzja: 78

from decimal import*
sum([Decimal(4/(i*2+1)*-1**i)for i in range(1e99**1e99)])

Źródło obrazu

Oddech terminalny

Ze względu na ogromne obliczenia, 1e99**1e99iteracje trwają niecałe 1e99**1e99lata. Teraz (1e99**1e99)-1e1000nie robi prawie żadnej różnicy. Oznacza to, że ten program będzie działał znacznie dłużej niż śmierć naszego wszechświata.

Odrodzenie

Teraz naukowcy proponują, że we 10**10**56 yearswszechświecie odrodzi się z powodu fluktuacji kwantowych lub tunelowania. Więc jeśli każdy wszechświat jest dokładnie taki sam, przez ile wszechświatów będzie żył mój program?

(1e99**1e99)/(1e10+1e1000+10**10**56)=1e9701

Zakładając, że wszechświat zawsze będzie żył 1e10+1e1000latami, a następnie 10**10**56latami „restartem”, mój program będzie żył przez 1e9701wszechświaty. Zakłada się oczywiście, że unobtainium może przetrwać Wielki Wybuch.

Rozpad beta
źródło
3
kończy się, gdy osiągnie koniec zakresu @Philipp. tak, to ostatecznie się kończy.
Malachi
1
1000**1000jest 1e3000, nie 1e2000.
Cornstalks
1
@Cornstalks Dzięki, nie miałem kalkulatora wystarczająco dobrego, aby go znaleźć, więc zgadłem na podstawie tego 100**100=1E200.
Beta Decay
1
@BetaDecay: Mogę zaproponować Wolfram | Alpha jako kalkulator online . Jeśli nigdy go nie używałeś, jest całkiem niesamowity!
Cornstalks
2
@ każdy zainteresowany lub 1000 ^ 1000 = (10 ^ 3) ^ 1000 = (10 * 10 * 10) * (10 * 10 * 10) * ... * (10 * 10 * 10) [1000 razy] = 10 ^ 3000
IazertyuiopI
12

Python 59 (działa przez większość czasu)

Nie mogłem się oprzeć

from random import*
while sum(random()for i in range(99)):0

Chociaż prawdą jest, że teoretycznie może to zakończyć się w ciągu milisekundy, średni czas działania jest znacznie dłuższy niż 10^400określony czas życia wszechświata. Dzięki @BetaDecay, @undergroundmonorail i @DaboRoss za sprowadzenie około 17 znaków.

KSab
źródło
Aby dostać się do 71 można zastąpić continuezpass
Beta Decay
@BetaDecay Nice catch
KSab
3
Myślę, że ponieważ pytanie dotyczy oczekiwanego czasu działania, nie jest problemem, że może to zakończyć się wcześniej. Większy problem polega na tym, że nie można w ogóle udowodnić jego zakończenia.
user19057,
4
@ user19057 Zakładając, co powiedział KSab, oczekiwany czas działania jest skończony, a program kończy się ze 100% prawdopodobieństwem. Oczywiście moduł losowy faktycznie korzysta z PRNG, który jest cykliczny, więc najprawdopodobniej nigdy się nie skończy.
Jerome Baum
1
Myślę, że możesz odciąć 3 znaki, zastępując „pass” „0”.
daboross
8

J - 5 znaków, tak myślę

Zauważ, że wszystkie poniższe elementy są arytmetyką o dowolnej precyzji, ponieważ liczba 9 zawsze ma trochę xobok siebie.

W siedmiu znaków, mamy !^:!!9x, która jest trochę jak bieganie

n = 9!
for i in range(n!):
    n = n!

z arytmetyką dowolnej precyzji. To zdecydowanie przekracza limit, ponieważ tak powiedział Synthetica , więc mamy górną granicę.

W sześciu znakach możemy również napisać ^/i.9x, który oblicza każdy wynik pośredni 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ 8. Wolfram | Alpha mówi, że 2^3^4^5^6^7^8jest w przybliżeniu 10 ^ 10 ^ 10 ^ 10 ^ 10 ^ 10 ^ 6.65185, co prawdopodobnie również czyści inspekcję.

Mamy również pięć znaków !!!9x, czyli po prostu ((9!)!) !. W | A mówi, że to 10 ^ 10 ^ 10 ^ 6.2695powinno być wystarczająco duże ... To jak 1.6097e1859933-cyfry, które są zdecydowanie większe niż 3.154e1016liczba nanosekund we wszechświecie, ale przyznam, że nie mam pojęcia, jak można to rozgryźć prawdziwe środowiska wykonawcze tych rzeczy.

Jednak samo drukowanie powinno trwać wystarczająco długo, aby trwało dłużej niż wszechświat, więc powinno być w porządku.

algorytmshark
źródło
7

C, 63 56 znaków

f(x,y){return x?f(x-1,y?f(x,y-1):1):y+1;}main(){f(9,9);}

Jest to oparte na pomyśle faceta o imieniu Wilhelm. Mój jedyny wkład to skrócenie kodu do tego krótkiego (i nieczytelnego) fragmentu.

Udowodnienie, że się kończy, odbywa się przez indukcję.

  • Jeśli x wynosi 0, kończy się natychmiast.
  • Jeśli kończy się na x-1 i dowolnym y, to również kończy się na x, to samo można wykazać przez indukcję.

Udostępnianie indukcji krok po indukcji:

  • Jeśli y jest równe 0, istnieje tylko jedno wywołanie rekurencyjne z x-1, które kończy się przy założeniu indukcji.
  • Jeśli f (x, y-1) kończy się, wówczas f (x, y) również się kończy, ponieważ najbardziej wewnętrzne wywołanie f jest dokładnie f (x, y-1), a najbardziej zewnętrzne wezwanie kończy się zgodnie z hipotezą indukcyjną.

Oczekiwany czas działania to A (9,9) / 11837 sekund. Liczba ta ma więcej cyfr niż liczba kwarków w obserwowalnym wszechświecie.

kasperd
źródło
(Ab) użyj preprocesora i zdefiniuj m = main, r = return i z = 99999, a następnie przepisz swój program jako, f (x, y) {rx? F (x-1, y? F (x, y- 1): 1): y + 1;} m () {f (z, z);}, co zajmie niesamowicie długo :-)
ChuckCottrill
5
@ChuckCottrill Jeśli reguły zezwalają na programy, które wymagają określonych makr preprocesora, a te nie liczą się do długości programu, każde zadanie można rozwiązać za pomocą jednego znaku.
kasperd
6

Matlab ( 10 8 znaków)

1:9e1016

IMHO, większość wpisów próbuje za bardzo, obliczając duże, skomplikowane rzeczy. Ten kod po prostu zainicjuje tablicę 9x10 1016 double s, licząc w górę od 1, co zajmuje 7,2x10 ^ 1017 bajtów. Na nowoczesnym procesorze o maksymalnej przepustowości pamięci 21 GB / s lub 6,63x10 ^ 17 bajtów / rok zajmie to co najmniej 1,09x10 1000 lat, aby nawet zainicjować tablicę, nie mówiąc już o próbie wydrukowania jej, ponieważ nie zawracałem sobie głowy pomijanie danych wyjściowych za pomocą średnika końcowego. (;


stare rozwiązanie

nan(3e508)

Alternatywnie

inf(3e508)

Ten kod po prostu utworzy kwadratową macierz NaNs / nieskończoności o rozmiarze 3e508x 3e508 = 9e10168 bajtów podwójnych lub 7.2e1017bajtów.

Nicu Stiurca
źródło
1
Co to jest? 1016? To musi być 9999! (A może coś źle zrozumiałem?)
Mega Man,
@MegaMan Pytanie o problem prosi o dolną granicę czasu działania wynoszącą 10 ^ 1000 lat. Jako że grałem w golfa, nie chciałem się marnować i obliczać zbyt długo, więc próbowałem go zatrzymać tak szybko, jak to możliwe, po osiągnięciu progu. :)
Nicu Stiurca,
ah, ok, nie znałem tej zasady
Mega Man,
5

Perl, 16 znaków

/$_^/for'.*'x1e9

To buduje ciąg powtarzający się „. *” Miliard razy, a następnie używa go jako igły i stogu siana w dopasowaniu wyrażenia regularnego. To z kolei powoduje, że silnik regex próbuje wykonać każdą możliwą partycję ciągu o długości dwóch miliardów znaków. Zgodnie z tą formułą z Wikipedii istnieje około 10 35218 takich partycji.

Powyższe rozwiązanie ma długość 16 znaków, ale wymaga jedynie około 2 GB pamięci, co oznacza, że ​​można je uruchomić na prawdziwym komputerze. Jeśli założymy, że pamięć jest nieskończona i rozmiar rejestru skończonego (co prawdopodobnie nie ma sensu), można go skrócić do 15 znaków, jednocześnie znacznie zwiększając czas działania:

/$_^/for'.*'x~0

(Nie testowałem tego, ale myślę, że może działać z 32-bitowym Perlem zbudowanym na 64-bitowym komputerze z co najmniej 6 GB pamięci RAM).

Uwagi:

  • x jest operatorem powtarzania łańcucha.
  • fornie jest rzeczywiste pętli; służy tylko do uratowania jednej postaci (w porównaniu do $_=".*"x1e9;/$_^/).
  • ^fraza końcowa wyrażenia regularnego zapewnia dopasowanie tylko pustego łańcucha; ponieważ kwantyfikatory regularne są domyślnie zachłanne, jest to ostatnia rzecz, którą silnik spróbuje.
  • testy porównawcze na moim komputerze dla wartości (1..13) sugerują, że czas działania to tak naprawdę O (exp (n)), co jest nawet więcej niż O (exp (sqrt (n))) we wzorze Wikipedii.
Umorusany
źródło
4

J (12)

(!^:(!!9))9x

Do czego to sprowadza się w Pythonie (zakładając, że !działa):

a = 9 
for i in range((9!)!):
    a = a!

EDYTOWAĆ:

Cóż, program może zająć najwyżej 2 × 10^-1858926kilka sekund na cykl, aby ukończyć go w wymaganym czasie. Wskazówka: to nie zadziała nawet w pierwszym cyklu, nie mówiąc już o ostatnim;).

Ponadto: ten program może wymagać więcej pamięci niż entropia we wszechświecie ...

.ıʇǝɥʇuʎs
źródło
3
„może potrzebować więcej pamięci niż entropia we wszechświecie” - Możesz to ograniczyć za pomocą xrange();)
Stefan Majewsky
1
Ponadto !nie działa w Pythonie. Potrzebujesz import mathi math.factorial().
daviewales
4

C # 217

Nie jestem wielkim golfistą, ale nie mogłem się oprzeć funkcji Ackermana . Nie bardzo wiem też, jak obliczyć czas działania, ale na pewno się zatrzyma i na pewno będzie działał dłużej niż ta wersja .

class P{
static void Main(){for(int i=0;i<100;i++){for(int j=0;j<100;j++){Console.WriteLine(ack(i,j));}}}
static int ack(int m,int n){if (m==0) return n+1;if (n ==0) return ack(m-1,1);return ack(m-1,ack(m,n-1));}
}
Gumowa kaczuszka
źródło
Możesz zapisać 10 bajtów, zmieniając nazwę ackfunkcji na nazwę jednoznakową, np a.
pppery
4

Pierwsza próba kodowania golfa, ale proszę bardzo.

VBA - 57 45

x=0
do
if rnd()*rnd()<>0 then x=0
x=x+1
while 1=1

Zatem X wzrośnie o jeden, jeśli wystąpi zdarzenie 1 na 2 ^ 128 i zresetuje, jeśli nie wystąpi. Kod kończy się, gdy to zdarzenie nastąpi 2 ^ 64 + 1 razy z rzędu. Nie wiem, jak zacząć obliczać czas, ale sądzę, że jest ogromny.

EDYCJA: Wyliczyłem matematykę, a prawdopodobieństwo tego w każdej pętli wynosi 1 na 2 ^ 128 ^ (1 + 2 ^ 64) i ma długość około 20000 cyfr. Zakładając, że 1000000 pętli / sek. (Ballpark z cienkiego numeru powietrza) i 30000000 s / rok to 3 * 10 ^ 13 cykli rocznie, pozostało 10 ^ 1000 lat to 3 * 10 ^ 1013 cykli, więc prawdopodobnie trwałoby to około 20 razy więcej niż pozostały czas we wszechświecie. Cieszę się, że moja matematyka wspiera moją intuicję.

Myles Horne
źródło
Myślę, że ostatnia linia powinna być While x=1, prawda? (w przeciwnym razie jest to nieskończona pętla). Ponadto, można zgolić 12 znaków, jeśli zastąpi Dim x As Doublesię x=0(VBA nie wymaga deklarowania zmiennych, chyba że podasz Option Explicit)
kb_sou
Nie patrzę na to jako na nieskończoną pętlę, ponieważ pęka, gdy x się przepełnia, co w końcu jest.
Myles Horne,
Zdecydowanie nie działa z tym, że x = 1, ponieważ generalnie uniemożliwiłoby to uruchomienie pętli.
Myles Horne,
Jeśli przerwanie w ten sposób pętli nie spełnia kryteriów „brak nieskończonych pętli”, WHILE 1 = 1 może zmienić się na WHILE ISNUMERIC (X).
Myles Horne,
4

C, 30 znaków

main(i){++i&&main(i)+main(i);}

Zakładając przepełnienie komplementu dwóch i 32-bitowe inty, będzie to działać dla około 2 2 32 wywołań funkcji, co powinno zająć dużo czasu dla końca wszechświata.

Uristqwerty
źródło
Jednak na długo przed tym skończy Ci się stos.
Sparr
1
@Sparr Jedną z zasad jest zakładanie nieskończonego rozmiaru stosu i sterty.
scragar
3

GolfScript, 13 znaków

0{).`,9.?<}do

Ten program po prostu liczy się od 0 do 10 9 9 -1 = 10 387420488 . Zakładając optymistyczne, że komputer działa na 100 GHz może wykonać iteracji programu w jednym cyklu programu na 10 9 9 -12 sekund lub około 3 x 10 9 9 -20 = 3 x 10 387420469 lat

Aby przetestować program, możesz zamienić na 9a 2, co spowoduje, że zatrzyma się na 10 2 2 −1 = 10 3 = 1000. (Użycie a 3zamiast a 2spowoduje, że zatrzyma się na 10 3 3 −1 = 10 26 , co , nawet przy powyższych optymistycznych założeniach nie osiągnie co najmniej kilku milionów lat).

Ilmari Karonen
źródło
3

Autohotkey 37

loop {
if (x+=1)>10^100000000
break
}
Person93
źródło
3

Haskell, 23

main=interact$take$2^30

Program kończy się po odczytaniu 1073741824 znaków z stdin. Jeśli jest uruchamiany bez przesyłania żadnych danych stdin, będziesz musiał wpisać tę liczbę znaków na klawiaturze. Zakładając, że klawiatura ma 105 klawiszy, z których każdy ma 100 000 cykli mechanicznych i jest zaprogramowany do generowania nieumarłych naciśnięć klawiszy, automatyczne powtarzanie jest wyłączone, a gniazdo klawiatury pozwala na 100 cykli połączeń, co daje maksymalną liczbę naciśnięć klawiszy na komputer wynoszącą 1050000000, co jest wartością nie wystarczy, aby program się zakończył.

Dlatego program zostanie zakończony tylko wtedy, gdy lepszy sprzęt będzie dostępny pod względem liczby cykli, czego w rzeczywistości nigdy nie ma w tym działającym wszechświecie. Może następnym razem, gdy jakość będzie miała wyższy priorytet niż ilość. Do tego czasu program ten kończy się w zasadzie, ale nie w praktyce.

TheSpanishInquisition
źródło
Co się stanie, jeśli będziesz wymieniać klawiatury podczas pracy?
Thomas
Jest to objęte 100 cyklami połączeń gniazda klawiatury.
TheSpanishInquisition
Ale punktem problemu jest to, że program ma zakończyć gdzieś po śmierci cieplnej wszechświata. Ten program nigdy nie może się zakończyć; gdy entropia stanie się wystarczająco wysoka, nigdy nie będziesz mieć innej klawiatury do podłączenia.
abarnert
1
Wciąż nie jestem przekonany. Jeśli uruchomisz program zdalnie (lub na maszynie wirtualnej), nie będziesz ograniczony możliwościami sprzętowymi pojedynczego komputera, a 1 miliard pociągnięć to naprawdę niewiele. Poza tym problem mówi, że komputer jest wykonany z unobtainium, a więc klawiatura powinna być, więc może obsłużyć 2 ^ 30 naciśnięć klawiszy ...
Thomas
3

~ ATH, 56

W fikcyjnym języku ~ ATH :

import universe U;
~ATH(U) {
} EXECUTE(NULL);
THIS.DIE()

~ ATH to nieznośny język do pracy. Jego logika składa się wyłącznie z nieskończonych pętli lub w najlepszym razie pętli o nieskończenie długiej konstrukcji.

Wielu programistów ~ ATH importuje skończone konstrukcje i wiąże pętle z ich żywotnością. Na przykład główna pętla zakończy się wraz ze śmiercią wszechświata, oznaczoną literą U. W ten sposób trzeba czekać miliardy lat, aż się skończy, a nie na zawsze.

Przepraszam za pogwałcenie granic; Pomyślałem, że to zbyt istotne, żeby to pominąć.

Jeśli ktoś był tym rozbawiony, więcej szczegółów: (1) , (2) , (3) , (4)

DBN
źródło
2

Rubin (34)

Linia ([0]*9).permutation.each{print}trwa około 2,47 sekundy na 9! drukuje na mojej maszynie, podczas gdy linia ([0]*10).permutation.each{print}zajmuje około 24,7 sekundy na 10! drukuje, więc myślę, że mogę tutaj ekstrapolować i obliczyć, (24.7/10!)*470! seconds in yearsktóra wynosi 6,87 * 10 ^ 1040, co powinno być czasem wykonania:

([0]*470).permutation.each{print}
Boris
źródło
2

JavaScript 68 62 znaków

(function a(m,n){return m==0?n+1:a(m-1,n==0?1:a(m,n-1))})(5,1)

Korzysta z funkcji Ackermanna, którą można zapisać jako

function ackermann(a, b) {
  if (a == 0) return b + 1;
  if (b == 0) return ackermann(a-1, 1);
  else return ackermann(a-1, ackermann(a, b-1));
}

Jego czas działania wydłuża się wykładniczo, dlatego jego obliczenie zajmuje bardzo dużo czasu. Nawet jeśli to nie jest język angielski tutaj można uzyskać przegląd jego wartości zwracanych. Zgodnie z tabelą ackermann(5,1)równa 2↑↑(65533)-3się, wiesz, bardzo duża.

henje
źródło
2
Może to skorzystać z niektórych takich samych optymalizacji, jak we wcześniejszej implementacji funkcji Perla Ackermanna.
Peter Taylor
Musiałem przeoczyć rozwiązanie perla. Dzięki za zwrócenie na to uwagi.
henje
zamiast tego n==0?X:Yzawsze możesz to zrobićn?Y:X
Cyoce
2

Befunge '93 - 40 bajtów

(Program 20x2)

v<<<<<<<<<<<<<<<<<<<
>??????????????????@

Ten program opiera się na losowych liczbach, aby zapewnić mu opóźnienie. Ponieważ tłumacze Befunge są dość powolne, ten program powinien pasować. A jeśli nie, zawsze możemy go rozwinąć w poziomie. Nie jestem do końca pewien, jak zacząć obliczać oczekiwany czas działania tego programu, ale wiem, że każdy? ma szansę 50/50 na rozpoczęcie od nowa lub zmianę pozycji poziomej o 1. Jest 18? Myślę, że powinno to być coś w stylu (18 ^ 2) !, który według kalkulatora Google mówi „Infinity”

EDYCJA: Ups, nie zauważyłem drugiej odpowiedzi Befunge, to mój pierwszy post tutaj. Przepraszam.

rodolphito
źródło
Hej, nie przejmuj się inną odpowiedzią befubnge, lub, ogólnie rzecz biorąc, używając tego samego języka, co ktoś inny. Chodzi mi o to, że nikt nie pokona matematyki, więc wszystkie pozostałe zgłoszenia dotyczą zabawy. Moje było.
AndoDaan
2

APL, 10

Nie sądzę, żeby to była poprawna odpowiedź (ponieważ jest niedeterministyczna), ale w każdym razie ......

{?⍨1e9}⍣≡1

Ten program oblicza losową permutację liczb 1e9 ( ?⍨1e9) i powtarza, aż dwa kolejne wyjścia będą równe ( ⍣≡)

Za każdym razem, gdy obliczana jest permutacja, ma ona wartość 1 na 1000000000! szansa na zakończenie. I 1000000000! wynosi co najmniej 10 10 8 .

Czas potrzebny do obliczenia permutacji staje się nieistotny z uwagi na masywność 1000000000! Ale niektóre testy pokazują, że tak jest, O(n)a ekstrapolacja daje około 30 sekund.

Jednak mój interpreter odmawia przyjęcia danych wejściowych do funkcji losowej większej niż 2 31 -1 (więc użyłem 1e9), a generowanie permutacji liczb 1000000000 dało pełny błąd obszaru roboczego. Jednak koncepcyjnie można tego dokonać za pomocą idealnego interpretera APL z nieskończoną pamięcią.

To prowadzi nas do możliwości użycia 2 63 -1 zamiast 1e9 w celu zwiększenia czasu działania do co najmniej 10 10 20 , przy założeniu architektury 64-bitowej.

Ale poczekaj, czy architektura jest odpowiednia w idealnym tłumaczu? Do diabła nie, więc tak naprawdę nie ma górnej granicy czasu pracy !!

TwiNight
źródło
2

R, 45 bajtów

(f=function(x)if(x)f(x-1)+f(x-1)else 0)(9999)

To stary wątek, ale nie widzę odpowiedzi R i nie możemy tego mieć!

Dla mnie czas działania wynosił około 1 sekundy, gdy x wynosił 20, co sugeruje czas działania 2 ^ 9979 sekund.

Jeśli zamienisz zero na jeden, wówczas wynik wyniósłby 2 ^ x, ale w takim stanie wynik jest zerowy bez względu na x (pozwala uniknąć problemów z przepełnieniem).

JDL
źródło
1

JavaScript, 120 bajtów

a=[0];while(a.length<1e4)(function(){var b=0;while(b<a.length){a[b]=(a[b]+1)%9;if(a[b])return;b++}a.push(1)})();alert(a)

Można to zrobić przy minimalnej pamięci (prawdopodobnie mniej niż pół megabajta), ale zatrzymanie zajmuje (prawdopodobnie) około 10 8750 lat.

Wielokrotnie zwiększa małą-endianową bazę-9 BigInteger, aż osiągnie 9 10 4 -1 .

SuperJedi224
źródło
1

Python 3, 191 bajtów

from random import*
r=randint
f=lambda n:2if n<2else f(n-1)
x=9E999
s=x**x
for i in range(f(x)**f(s)):
 while exec(("r(0,f(x**i))+"*int(f(x)))+"r(0,f(x**i))")!=0:
  s=f(x**s)
  print(s)

Po pierwsze, f jest rekurencyjną funkcją czynnikową i ultra wolną. Następnie jest zasilany 9 * 10⁹⁹⁹, który generuje błąd przepełnienia, ale nie dzieje się tak na tym komputerze Unobtanium. For-Loop iteruje 9E999! ^ (9E999 ^ 9E999)! razy i przechodzi tylko do następnej iteracji, jeśli 9E999! +1 losowe ints od 0 do 9E99 * ^ i! wszystkie są równe 0 i w każdej iteracji pętli while ustawiane jest na (9E999 ^ s)! Uh, zapomniałem, że drukowanie s zajmuje muuuuccchhhh czas ...
Wiem, że to nie jest najkrótsze rozwiązanie, ale myślę, że to naprawdę skuteczne. Czy ktoś może mi pomóc w obliczeniu czasu pracy?

Mega człowiek
źródło
1

Maszyna Turinga, ale gorzej , 167 bajtów

0 0 1 1 2 0 0
1 0 1 0 4 0 0
0 1 1 1 2 0 0
1 1 1 1 5 0 0
0 2 1 0 3 0 0
1 2 0 1 1 0 0
0 3 1 1 4 0 0
1 3 0 0 2 0 0
0 4 1 0 0 0 0
1 4 0 1 3 0 0
0 5 1 0 6 0 1
1 5 1 1 2 0 0

Wypróbuj online!

Powinien uruchomić 6-stanowy 2-symbolowy Busy Beaver ze strony Wikipedii .

7.412×1036534

MilkyWay90
źródło