Powolny wzrost Quine

30

Zrób Quine.

Wydaje się łatwe, prawda? Cóż, ta quine musi wypisać samą siebie i swój pierwszy znak, a następnie wypuścić siebie i swój drugi znak, i tak dalej.

W ten sposób quine powinno w ciągu kilku generacji generować dwie kopie.

Przykład: pozwala na kod x. Uruchomienie powinno dać wynik x + x[:1]. Uruchomienie wynikowego programu powinno zostać wyprowadzone x + x[:2]i tak dalej ...

Jeśli twój kod był foobar, uruchomienie powinno dać wynik foobarf. Uruchomienie tego powinno dać wynik foobarfo. I tak dalej i tak dalej zgodnie z tym wzorem:

foobar
foobarf
foobarfo
foobarfoo
foobarfoob
foobarfooba
foobarfoobar
foobarfoobarf

Twój program musi być dłuższy niż 2 bajty i musi wypisywać tylko JEDEN dodatkowy znak własnego kodu w każdej iteracji.

IQuick 143
źródło
3
Podejrzewam, że wyzwanie to jest niemożliwe w większości języków, biorąc pod uwagę, że czytanie kodu źródłowego jest domyślnie zabronione.
Ørjan Johansen
12
@ ØrjanJohansen, a potem pojawia się Dennis
Rod
2
@Rod Cóż, nie powiedziałem wszystkiego , po prostu wiele / większość języków nie ma oczywistego sposobu na dodanie dowolnych fragmentów kodu na końcu w taki sposób, że (1) nie powoduje błędu składniowego (2) program może wykryć zmianę.
Ørjan Johansen
3
Ponieważ jest to bardzo niezwykły quine, czy zwykłe luki w quine nadal są niedozwolone?
Draconis

Odpowiedzi:

15

Zsh ,110 108 100 bajtów

a=`<&0`<<''<<<t;b=${a:0:50};printf $b$b${a:0:-50}
a=`<&0`<<''<<<t;b=${a:0:50};printf $b$b${a:0:-50}

Wypróbuj online!

To jest możliwe.

Wyjaśnienie

a=`<&0`<<''<<<t;       # Set A to everything following this line, until eof or
                       #   an empty line (which never happens before eof) encountered.
                       # A "t" is appended to prevent automatic trimming of newlines.
b=${a:0:50};           # Set B to the first line.
printf $b$b${a:0:-50}  # Print two copies of B and
                       #   A with 50 trailing characters removed.
jimmy23013
źródło
11

R, 289 bajtów

s<-c("s<-", "i=get0('i',ifnotfound=0)+1;p=paste0(s,substr(get0('p',ifnotfound=s),1,i),collapse='');cat(s[1]);dput(s);cat(paste0(s[2],substr(p,1,i)))#")
i=get0('i',ifnotfound=0)+1;p=paste0(s,substr(get0('p',ifnotfound=s),1,i),collapse='');cat(s[1]);dput(s);cat(paste0(s[2],substr(p,1,i)))#

kredyt do tej Quine'a inspiracji. Działa tylko, jeśli działa w tym samym środowisku R, co poprzednia quine.

Giuseppe
źródło
wyjaśnienie będzie wkrótce ... Nie przetestowałem go jeszcze 288 razy, ale jestem całkiem przekonany, że jest poprawne
Giuseppe
Powinno to mieć 289 bajtów, ponieważ quine dodaje tam znak nowego wiersza, ale i tak świetnie, że go rozwiązałeś!
IQuick 143
ah, masz rację, głupio catdodając nowe linie.
Giuseppe
Ale czy to pełny program? Czy wygenerowany kod jest pełnym programem?
jimmy23013
@ jimmy23013 O ile wiem, ta odpowiedź i wygenerowany kod są pełnymi programami. W mainR. nie ma żadnej innej obowiązkowej struktury takiej jak ta. Poza tym pytanie wyraźnie nie wymaga pełnego programu, więc spełniałaby to funkcja lub podobne.
Steadybox
5

Alice , 29 bajtów

4P.a+80pa2*&wdt,kd&w74*,.ok@

Wypróbuj online!

Znak niedrukowalny to 0x18.

Wyjaśnienie

Problem ze zwykłymi "quinesami Fungeoid polega na tym, że jeśli powtórzymy cały kod źródłowy, otrzymamy również dodatkowy, "a ciąg nie będzie już obejmował całego kodu źródłowego. Zakładam, że dlatego w istniejącej odpowiedzi zastosowano gpodejście cheat-y .

Ta odpowiedź korzysta z "podejścia opartego na zasadach, ale zamiast dołączać a "do źródła, piszemy ją do programu w czasie wykonywania. W ten sposób będzie tylko jeden, "niezależnie od tego, jak często program się powtarza (ponieważ zapisujemy go tylko do jednej określonej współrzędnej, niezależnie od wielkości programu).

Ogólna idea polega na tym, że tworzymy reprezentację całego kodu źródłowego na stosie, ale cyklicznie przechodzimy przez pierwsze 29 znaków (tj. Długość programu), przy czym długość pętli zależy od wielkości kodu. Dlatego możemy faktycznie dodawać dowolne znaki (z wyjątkiem linii) po, @a wynikiem będzie zawsze cykliczne powtarzanie programu podstawowego, jeden znak dłuższy niż źródło.

4P   Push 4! = 24. This is the code point of the unprintable, which we're 
     using as a placeholder for the quote.
.a+  Duplicate it and add 10, to get 34 = '"'.
80p  Write '"' to cell (8,0), i.e. where the first unprintable is.
    Placeholder, becomes " by the time we get here, and pushes the code
     points of the entire program to the stack. However, since we're already
     a good bit into the program, the order will be messed up: the bottom
     of the stack starts at the 24 (the unprintable) followed by all 
     characters after it (including those from extraneous repetitions). Then 
     on top we have the characters that come in front of the `"`. 
     So if the initial program has structure AB, then any valid program has
     the form ABC (where C is a cyclic repetition of the initial program),
     and the stack ends up holding BCA. We don't care about C, except to
     determine how big the program is. So the first thing we need to do is
     bring B to the top, so that we've got the initial program on top of
     the stack:
a2*  Push 10*2 = 20.
&w   Run the following section 21 times, which is the length of B.

  dt,  Pull up the value at the bottom of the stack.

k    End of loop.
d&w  Run the following section D+1 times, where D is the length of ABC.

  74*  Push 28, one less than the number of characters in AB.
  ,    Pull up the 29th stack element, which is the next character to print.
  .o   Print a copy of that character.

k    End of loop.
@    Terminate the program.
Martin Ender
źródło
Świetne rozwiązanie. Lubię to wyjaśnienie.
IQuick 143
4

Perl 5 , 83 bajtów (w tym końcowy nowy wiersz)

$_=q($/=$;;$_="\$_=q($_);eval
__END__
".<DATA>;print$_,/(.).{82}\z/s);eval
__END__

Wypróbuj online!

Dobry ol ' __DATA__token ułatwia dołączenie dowolnego ciągu znaków do dowolnego programu w Perlu, do którego program główny może uzyskać dostęp za pośrednictwem <DATA>uchwytu pliku (i faktycznie używa tego __END__, co robi to samo dla kompatybilności wstecznej, zamiast __DATA__oszczędzać dwa dodatkowe bajty) .

Zauważ, że ten program nie odczytuje własnego kodu źródłowego, a jedynie dodatkowe dane wejściowe dołączane do źródła po __END__tokenie. W efekcie __END__token i wszystko po nim działa jak literał łańcuchowy zakończony na końcu danych wejściowych.

Należy również pamiętać, że aby dokładnie spełnić specyfikację, ten program musi kończyć się nową linią. Jeśli nie, nowa linia i tak jest automatycznie dodawana po drugim __END__, ale wtedy wynik pierwszej iteracji nie będzie już dokładnie równy kodowi plus jego pierwszy bajt.

Ilmari Karonen
źródło
2

Befunge-98 , 30 bajtów

0>:#;0g:840#;+*#1-#,_$a3*%0g,@

Wypróbuj online!

Moja próba użycia Befunge-98, która używa spinu zakończonego spacją, który również liczy, ile znaków zostało wyprowadzonych. Używa jednak gpolecenia.

IQuick 143
źródło
Możesz wspomnieć w pierwszym wierszu, że to nie konkuruje / nie oszukuje, aby zniechęcić do jakichkolwiek negatywnych opinii, które w przeciwnym razie mogłyby otrzymać.
kwintopia
2

PHP, 146 bajtów

ob_start(function($s){return($u=substr($s,0,73)).$u.substr($s,0,-72);})?>ob_start(function($s){return($u=substr($s,0,73)).$u.substr($s,0,-72);})?>

Powinien być uruchamiany za pomocą -rwiersza poleceń.

jimmy23013
źródło
Nie działa, gdy próbuję online! , to zwykły quine.
Ørjan Johansen
@ ØrjanJohansen Powinieneś go uruchomić php -r 'command'.
jimmy23013
Gah, nie mogę go uruchomić. TIO wydaje się po prostu ignorować argumenty -r.
Ørjan Johansen
Aha. Musiałem wtedy coś źle zrozumieć. Teraz udało mi się sprawić, aby działał również z PHP jako ustawieniem języka .
Ørjan Johansen
2

Runiczne Zaklęcia , 61 bajtów

803X4+kw.'.q}͍}͍}͍}͍}͍}͍}͍}͍}͍::l͍5X-:}-$:l͍{-1--@

Wypróbuj online!

Stosuje podobne podejście jak odpowiedź Alice: refleksyjnie zapisuje "komendę łańcuchową w kodzie, aby istniała tylko jedna. Pozostaje wiele operacji na łańcuchach i stosach, aby odzyskać oryginalny program, ile dodatkowych bajtów jest potrzebnych i wydrukować niezbędne porcje.

Sekwencja obraca reprezentację w pamięci ciąg wokół tak, że 803X4+kwpojawia się na początku zamiast na końcu, z powodu położenia punktu "i nie ma łatwiejszy sposób obsługi tej operacji bez konieczności obliczyć wiele liczb niewygodnych .

Podczas gdy oryginalny program ma 61 bajtów, jego długość łańcucha wynosi tylko 50, co jest łatwe do skonstruowania, 5Xa zbiegiem okoliczności nie trzeba było go uzupełniać po wprowadzeniu wszystkich niezbędnych funkcji (np. Program o długości 49 byłby łatwiejszy aby zakodować jak 50z jednym bajtem dopełniania, niż zakodować literał 49, podczas gdy 51byłby zakodowany jako 5X3+lub 53, z uwzględnieniem własnych dodatkowych bajtów).

Draco18s
źródło