Napisz najdłuższy okres iteracji quine ograniczony przez 500 bajtów

16

Twoim zadaniem jest stworzenie najdłuższego okresu iteracji , w którym długość każdego programu w sekwencji jest ograniczona przez 500 bajtów.

Oznacza to, że jeśli powtórzysz następujące kroki:

  1. Zacznij od pierwszego programu
  2. Uruchom bieżący program
  3. Wróć do kroku 2

W końcu wrócisz do swojego oryginalnego programu. Liczba programów w cyklu to Twój wynik, który próbujesz zmaksymalizować.

Żaden z programów nie może zgłaszać żadnych błędów. Każdy program musi być również uruchomiony w ten sam sposób (np. Nie ma różnych wersji, implementacji, opcji kompilatora, platform itp.) (EDYCJA: Tak, każdy stan zewnętrzny, taki jak generator pseudolosowych liczb, został uwzględniony w ostatnim instrukcja. Stan zewnętrzny musi być „resetowany” po każdym uruchomieniu. Jeśli używasz prawdziwych liczb losowych, przyjmuje się, że najgorszy przypadek.

Tym, co odróżnia to wyzwanie od najdłuższego okresu iteracji quine (innego niż 100 vs 500) jest to, że każdy program w cyklu musi mieć również 500 bajtów lub mniej. Oznacza to, że najdłuższy możliwy cykl to (256 ^ 501 - 1) / 255 lub mniej. To oczywiście duża liczba, ale nie tak duża pod względem ilości kodu potrzebnej do obliczenia. Wyzwanie polega więc na wykorzystaniu jak największej liczby (256 ^ 501 - 1) / 255 możliwości, a nie na zajęciu bobra.

Programy nie mają dostępu do własnego kodu źródłowego. Jednak pusty program jest dozwolony, jeśli chcesz (pod warunkiem przestrzegania innych zasad).

Ponieważ ręczne sprawdzanie programów byłoby trudne, możesz ustalić wynik przy użyciu metod teoretycznych. Do swojego programu musisz dołączyć wyjaśnienie wyniku i poprawności. Jeśli nie możesz ustalić wyniku, możesz zamiast tego użyć dolnej granicy liczby programów w cyklu jako wyniku defacto. Możesz to aktualizować, gdy znajdziesz lepsze dolne granice lub jeśli znajdziesz dokładny faktyczny wynik.

To jest , więc najwyższy wynik wygrywa!

EDYCJA: Zaleca się zapisanie wyniku w notacji naukowej, aby odpowiedzi były łatwiejsze do porównania. Zupełnie dobrze jest mieć również inne formy partytury, szczególnie jeśli są one wyraźniej powiązane z twoim programem. Zachęcamy również czytelników do edycji poprzednich odpowiedzi w celu zapewnienia zgodności z tym.

PyRulez
źródło
2
„najdłuższy możliwy cykl to (256 ^ 501 - 1) / 255 lub mniej” --- to niekoniecznie prawda, program może wielokrotnie przejść przez ten sam stan przed powrotem do oryginału, jeśli manipuluje obiektem zewnętrznym ( takich jak stan RNG lub ziarno)
JDL
2
@JDL, które powinno być niezgodne z regułami, IMHO - jeśli przechowuje stan w innym miejscu niż w kodzie źródłowym, to nie jest to właściwa iterująca quine.
Nathaniel
1
@Nanielski Nie sklasyfikowałbym tego jako przechowywania stanu w innym miejscu, po prostu używa punktów wejścia, które są prawidłową częścią języka programowania, w którym jest implementowany. Prawdopodobnie wszystko, co wywołuje inną funkcję w języku programowania, ma dostęp do stanów, które są przechowywane na zewnątrz własny kod źródłowy.
JDL
1
@JDL nie, to są różne rzeczy. Każdy program w dowolnym języku musi oczywiście polegać na rzeczach zaimplementowanych poza kodem źródłowym, ale przechowywanie stanu poza kodem źródłowym jest inne. Oznaczałoby to, że wyjście programu nie jest deterministyczną funkcją jego kodu źródłowego, ale zależy od jakiegoś innego kontekstu zewnętrznego, który został zmieniony przez poprzednie uruchomienia. Nie powinno to być dozwolone w przypadku quine Challenge, IMHO, a oświadczenie OP o maksymalnej długości cyklu wskazuje, że zamierzano go tutaj zabronić.
Nathaniel
3
@JDL, bo jestem pewien, że wiesz, że w języku deterministycznym wskaźnik instrukcji przechowuje stan tylko podczas wykonywania programu, a nie między jego wywołaniami. Twój 5-stanowy przykład nie jest możliwy, jeśli wyjście programu jest deterministyczną funkcją jego źródła.
Nathaniel

Odpowiedzi:

12

Perl 6 , 1263988,86×10835 iteracji

$!=Q~~;<say "\$!=Q~{chrs(my@a=[R,] polymod :126[$!.ords]+1: 126 xx*)x?(@a-399)}~;<$_>~~.EVAL">~~.EVAL

Wypróbuj online!

Powtarza to wszystkie możliwe kombinacje pierwszych 126 bajtów o długości 398 i mniejszych (z wyłączeniem ciągów z wiodącymi bajtami NUL). Jeśli chcesz zobaczyć, że faktycznie powraca do pierwszej iteracji, możesz zmniejszyć długość do 1, zmieniając limit w ten sposób .

Wyjaśnienie:

Każda iteracja zwiększa ciąg, przechowywany w formie podstawowej 126, a następnie przekształca go z powrotem w podstawę 126. Robi to, dopóki nie osiągnie ciągu o długości 399, a następnie resetuje ciąg ponownie z powrotem do opróżnienia. Jeśli masz problem z konceptualizacją liczby, wyobraź sobie, że ma ona dziesięć bajtów. Zaczynając od 0, zwiększ maksymalnie 4 cyfry 1000i zresetuj. To jest 104-1 iteracji (włączając 0lub pusty ciąg w przypadku mojego programu).

$!=Q~~;         # Start with an empty string
< ... >~~.EVAL  # Set a string to $_ and EVAL it
  say "\$!=Q~{...}~;<$_>~~.EVAL"   # Print the program with the string replaced by
                       :126[$!.ords]   # The string converted from base 126
                                    +1 # Incremented
          [R,] polymod                : 126 xx*  # Back to base 126
chrs(                                )  # Back to a string
     my@a=                            x?(@a-399)  # Only if it isn't 399 characters
Jo King
źródło
1
Wow, zrobiłeś to naprawdę szybko, prawie skończyłem z moim, ale prawdopodobnie skończę go jutro (mój będzie w Gol> <>)
KrystosTheOverlord
Obliczenia te sugerują, że znacznie przekroczyłeś swój wynik. Licznik określa, ile łańcuchów o długości 397 używa 126 symboli. (Musiałem rozdzielić ułamek na sumę, ponieważ wolfram alfa zachowywał się dziwnie.)
PyRulez 11.02.19
@PyRulez Myślę, że mój numer jest poprawny, ponieważ w zasadzie iteruje podstawową liczbę 126 do 399 cyfr ... Myślę, że moje wyjaśnienie było wyłączone
Jo King
@JoKing ah tak, myślę, że wyjaśnienie było problemem. Zmieniłeś 397 na 398, co sprawia, że ​​Twój wynik nie jest już przeceniony. Być może nie doceniasz tego (ponieważ w zapisie uwzględniłeś tylko ciągi długości dokładnie 398), ale to w porządku.
PyRulez
2

Runiczne Zaklęcia , 64654 106 ; 122 387 -1 ≈ 2,638 × 10 807 iteracji

"3X4+kSq'ƃZ,r{1?{1[:1Z%1+:a=+:d=+:3X4+=+:6X2+=+:'€(c*?~1-1kq}͍f1+0Bl1=6*?S1-Skql͗2=4*?{͍]}B͍l1=6*?kS1-Sq]}@

Wypróbuj online!

Alert: Niepoprawnie wyświetlane, powinno być `` (0x80).

Zamiast stosu należy użyć ciągu, a operatorzy stosu zmodyfikowali za pomocą, ͍aby zmodyfikować ciąg zamiast stosu (patrz poprzednia wersja). Jako taki, każdy znak jest ograniczony do 1 bajtu (zakres 0-127, minus problematyczne znaki), ale z ponad 3-krotnie większą liczbą (ze względu na mniejszą liczbę przetwarzanych znaków z powodu braku konieczności pomijania znaków łączących Unicode, ponieważ oraz inne oszczędności bajtów) osiąga większą liczbę iteracji.

Jeśli dozwolone jest kodowanie jako prawdziwy duży endian (tzn. Posiadanie wartości bajtów powyżej 127 bez wstawiania 0x00bajtów), można osiągnąć iteracje 251 387 -1 ≈ 4,717 × 10 928 . Jednak łacińskie kodowanie TIO zapobiega temu, jak zauważył Erik the Outgolfer w swojej odpowiedzi na Python 2. Musiałbym sprawdzić, czy to działa lokalnie, zanim zaczniesz uzyskiwać ten wynik.

Powinien być w stanie wymienić f1+0Bz '0B(Jest takie unprinting 0x16tam), ale walczy mnie (co nie chciała oddziale / SKIP / zwrotu poprawnie), więc zostawiłem go w spokoju. Podniosłoby to strukturę big-endian z 387 do 388.

Draco18s nie ufa już SE
źródło
1

DOS COM, 49 bajtów, okres 2 ^ 3608

00000000  be 31 01 89 f7 b9 f4 02  f9 ac 14 00 aa 39 ce 72  |.1...........9.r|
00000010  f8 31 c9 b4 3c ba 2b 01  cd 21 89 c3 b4 40 b9 f4  |.1..<.+..!...@..|
00000020  01 ba 00 01 cd 21 b4 3e  cd 21 c3 71 2e 63 6f 6d  |.....!.>.!.q.com|
00000030  00                                                |.|

Oryginalny zespół do utworzenia:

 BITS 16
 ORG 0100h
   mov si, l
   mov di, si
   mov cx, 500 + 0100h
   stc
n: lodsb
   adc al, 0
   stosb
   cmp si, cx
   jb n
   xor cx, cx
   mov ah, 3ch
   mov dx, f
   int 21h
   mov bx, ax
   mov ah, 40h
   mov cx, 500
   mov dx, 0100h
   int 21h
   mov ah, 3eh
   int 21h
   ret
f: db "q.com", 0
l: db 0

Ten mały klejnot zapisuje kolejną fazę na q.com zamiast standardowego wyjścia z powodu wartości zerowych i innych rzeczy, których terminal nie może obsłużyć. Technika root quine jest równoważna z rygoryzacją, a pokój danych jest wykorzystywany jako licznik 3608 bitów. Ze względu na sposób działania DOS, początkowy stan licznika zawiera zanieczyszczenia z wszystkiego, co było w pamięci przed jego pierwszym uruchomieniem.

Oryginalne 49 bajtowe dane wejściowe są nieosiągalne, więc jeśli chcesz uzyskać wynik w postaci 500 bajtów.

Jozuego
źródło
1

C # (interaktywny kompilator Visual C #) , flagi: /u:System.Numerics.BigIntegeri/r:System.Numerics

Wynik: 10 332

Dzięki JoKing, który zwiększył mój wynik z 10 255 * 2 - 1 do teraz!

var i=Parse("0");var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";Write(s,(char)34,s,(++i).ToString().Length<333?i:0);

Wypróbuj online!

Wyjaśnienie

Zwiększa wartość BigInteger w każdej iteracji, dopóki jej długość nie stanie się zbyt duża, co w takim przypadku natychmiast przywracamy do pierwotnej liczby.

//The BigInteger that will be incremented
var i=Parse("0");
//The string that encodes the quine
var s="var i=Parse({0}{2}{0});var s={0}{1}{0};Write(s,(char)34,s,(++i).ToString().Length<333?i:0);";
//Print out the string, with every {0} replaced with quotes and the {1} replaced with the original string
Write(s,(char)34,s,
//And the {2} is replaced to the BigInteger+1 if the BigInteger wouldn't be too long, else 0
(++i).ToString().Length<333?i:0);
Wcielenie ignorancji
źródło
1

252219

#coding=L1
s=""""""
for i in range(220-len(s.lstrip("ÿ")))[:219]:s=s[:i]+chr(ord(s[i])%255-~(s[i]in"!$&"))+s[i+1:]
S='#coding=L1\ns="""%s"""\nfor i in range(220-len(s.lstrip("\xff")))[:219]:s=s[:i]+chr(ord(s[i])%%%%255-~(s[i]in"!$&"))+s[i+1:]\nS=%%r;print S%%%%s%%%%S';print S%s%S

Zauważ, że jest nowy znak końca. Może zostać usunięty powyżej, jeśli wtargnie do niego wyróżniacz składni.

Niestety nie można uruchomić tego programu w TIO, ponieważ jest on zakodowany w Latin-1.

Powyżej szawiera 219 0x01 bajtów. Po uruchomieniu programu jego źródło jest drukowane, z wyjątkiem jednej różnicy: szostało zwiększone jak podstawowa liczba big-endian 252, więc jego lewy znak został „zwiększony” do 0x02. Unikane są bajty 0x00, 0x22, 0x25 i 0x5C, więc jeśli dowolny znak ciągu stanie się jednym z tych po inkrementacji, sam znak zostanie ponownie zwiększony.

  • 0x00 (null): Plik źródłowy Python nie może zawierać znaków null.
  • 0x22 ( "): Istnieje niebezpieczeństwo, że w rzędzie utworzą się trzy bajty 0x22 """, czyli ostatni znak łańcucha stanie się ", więc łańcuch zostanie przedwcześnie zamknięty.
  • 0x25 ( %): formatowanie ciągów podobnych do printf jest używane przed ukończeniem szkieletu quine, więc %nie sąsiadowanie z innym %w sspowoduje problemy. Niestety nie można zmienić kolejności formatowania, aby uniknąć tego zastrzeżenia.
  • 0x5C ( \): Istnieje możliwość \użycia znaku ucieczki w ciągu zamiast dosłownie, więc można go uniknąć.

Dlatego można użyć 252 z 256 bajtów. Jeśli szawiera 219 ÿbajtów 0xFF ( ), jest po prostu przywracany do 219 bajtów 0x01, co kończy cykl.

252219

252219=8067118401622543607173815381864126969021321378412714150085501148172081568355283332551767558738710128769977220628694979838777041634307806013053042518663967641130129748108465109552157004184441957823830340121790768004370530578658229253323149648902557120331892465175873053680188287802536817909195292338112618632542000472094347226540339409672851252596442228662174845397731175044304251123874046626291460659909127172435776359148724655575878680270692451120531744950544969860952702932354413767504109600742385916705785109741289800204288

Erik the Outgolfer
źródło
1

2512262.1×10542

  • 251 39 usunięto zależność odText
  • 251 122 golfowa funkcja inkrementacji
  • 251 128 połączonych ciągów źródłowych przedrostka i przyrostka
  • 251 188 usunięto zależność odGast.GenLibTest

Prezentowane w formacie XXD z powodu niedrukowalności / nieprawidłowego UTF-8:

00000000: 6d6f 6475 6c65 2071 3b69 6d70 6f72 7420  module q;import 
00000010: 5374 6445 6e76 3b53 7461 7274 3d28 7325  StdEnv;Start=(s%
00000020: 2830 2c34 3129 2c3f 5b27 0101 0101 0101  (0,41),?['......
00000030: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000040: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000050: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000060: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000070: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000080: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000090: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000a0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000b0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000c0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000d0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000e0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
000000f0: 0101 0101 0101 0101 0101 0101 0101 0101  ................
00000100: 0101 0101 0101 0101 0101 0101 275d 2c73  ............'],s
00000110: 2528 3432 2c39 3939 292c 712c 732c 7129  %(42,999),q,s,q)
00000120: 3b71 3d69 6e63 2721 273b 3f5b 683a 745d  ;q=inc'!';?[h:t]
00000130: 2363 3d68 2b69 6628 616e 7928 283d 3d29  #c=h+if(any((==)
00000140: 6829 5b27 ff09 0c26 5b27 5d29 2702 2727  h)['...&['])'.''
00000150: 0127 3d5b 633a 6966 2863 3e68 2969 643f  .'=[c:if(c>h)id?
00000160: 745d 3b3f 653d 653b 733d 226d 6f64 756c  t];?e=e;s="modul
00000170: 6520 713b 696d 706f 7274 2053 7464 456e  e q;import StdEn
00000180: 763b 5374 6172 743d 2873 2528 302c 3431  v;Start=(s%(0,41
00000190: 292c 3f5b 2727 5d2c 7325 2834 322c 3939  ),?[''],s%(42,99
000001a0: 3929 2c71 2c73 2c71 293b 713d 696e 6327  9),q,s,q);q=inc'
000001b0: 2127 3b3f 5b68 3a74 5d23 633d 682b 6966  !';?[h:t]#c=h+if
000001c0: 2861 6e79 2828 3d3d 2968 295b 27ff 090c  (any((==)h)['...
000001d0: 265b 275d 2927 0227 2701 273d 5b63 3a69  &['])'.''.'=[c:i
000001e0: 6628 633e 6829 6964 3f74 5d3b 3f65 3d65  f(c>h)id?t];?e=e
000001f0: 3b73 3d22                                ;s="

Wypróbuj online!

Zwiększa ciąg 226-bajtowy przez wszystkich wartości bajtowych wyjątkiem \0, \n, \r, 'i \.

Powodem, dla którego unikamy tych znaków, jest:

  • \0 denerwuje kompilator
  • \ni \rnie może pojawić się na listach charlistów
  • ' zakończyłby listę znaków
  • \ może powodować problemy, jeśli pojawi się przed postacią ucieczki

Gdy łańcuch jest już \377s, zawija się do wszystkich \001s, dając oryginalny program.

Obrzydliwe
źródło
Wyjście (przynajmniej w TIO) to znak o wartości porządkowej 128, ale złożony z dwóch bajtów C2 80. Czy to samo, co zachowanie na twoim komputerze lokalnym?
Jo King
1
@JoKing Och, nie, mam jeden bajt na mojej maszynie. TIO zmienia wyjście, gdy nie jest poprawne UTF-8 (i pliki wejściowe również).
Οurous
1
@JoKing Zmieniłem odpowiedź na nowy format, który pozwala zobaczyć prawidłowe zachowanie w TIO.
Οurous
0

Gol> <> , 70 bajtów, 39039000 iteracji

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPaa*5*=?1:1=Q$~$~|:1)lPaa*5*(Q?:|r2ssH##

Wow, to o wiele mniej niż myślałem, że będzie ... Następny krok! Dzięki temu ma więcej iteracji !!!

Wypróbuj online!

KrystosTheOverlord
źródło
wydaje się, że niczego nie usuwa, gdy osiągnie 500, po prostu dołącza bajt NUL
Jo King
Czy to w ogóle działa? Nie mogę uruchomić „przyrostu ostatniego znaku” do działania
tylko ASCII,
@ Tylko ASCII Teraz to działa, przepraszam za wcześniej. Zepsułem sekcję podczas pracy nad naprawą całej rzeczy. Teraz działa, przepraszamy za niedogodności !!!
KrystosTheOverlord
@JoKing Bajt NUL jest procesem usuwania, teraz program powinien usuwać, aż prawie zniknie, a następnie usuń NUL i zwiększ ostatni znak, jeśli jest ~, to zostanie przekonwertowany na „#”, powracając Do normalności!!!
KrystosTheOverlord