Zrób przeplatający quine

17

Twoim zadaniem jest stworzenie programu, który po uruchomieniu zwróci się jako wynik (jest to znane jako quine). Jednak ten quine musi, kiedy jest kopiowany nrazy, zwraca quine, ale z każdym jego znakiem powielonym w nczasie, gdzie njest dodatnią liczbą całkowitą.

Jeśli twój oryginalny program to Derp:

Derp -> Derp (must return itself as output to be a quine)

DerpDerp -> DDeerrpp
(the "Derp" is copied twice, so each character in the output has to be copied twice)

DerpDerpDerp -> DDDeeerrrppp
etc. etc.

Pamiętaj, że możesz mieć spacje w swoim programie „podstawowym”, ale są one liczone podczas „przeplatania”. Powiedz, że twój program to

Derp 
{newline}

(Nowa linia oznacza nową linię, a po niej jest spacja Derp). Gdy zostanie zduplikowany, aby zostać

Derp 
Derp 
{newline}

Musisz wyprowadzać

DDeerrpp  
{newline}
{newline}

Pamiętaj, że 2po DDeerrpp.

Zasady i specyfikacje:

To jest , więc wygrywa najkrótszy kod w bajtach!

clismique
źródło
1
„Obowiązują standardowe zasady” - czy to oznacza brak odczytu kodu źródłowego?
FlipTack,
@FlipTack To znaczy, że - przeczytaj link, aby uzyskać więcej informacji.
clismique

Odpowiedzi:

12

Rozszczepienie , 6 bajtów

'!+OR"

Wypróbuj online! Wypróbuj dwie kopie! Wypróbuj trzy!

Wyjaśnienie

To tylko standardowy quine Fission . Zdarza się, że działa na to wyzwanie, ponieważ Fission ma wyraźne punkty wejścia do programu. W szczególności, powielając program, dodajemy inny, Rktóry dodaje kolejny atom (wskaźnik instrukcji). Ponieważ kod źródłowy jest toroidalny, wykonywany kod efektywny nie zmienia się inaczej - dla każdego atomu kod nadal wygląda lokalnie tak samo. Jednak atomy są wykonywane w kroku blokady, dzięki czemu rzeczy, które drukują, są przeplatane i otrzymujemy dodatkową kopię każdego znaku na wyjściu.

Dla kompletności krótko powtórzę, jak działa sam program. Niezależnie od tego, czy powtarzamy program, czy nie (np. '!+OR"'!+OR"'!+OR"), Każdy atom widzi następujący kod:

R"'!+OR"'!+O

"Tryb drukowania przełącza ciąg tak, że program uruchamia się poprzez drukowanie '!+ORbezpośrednio na standardowe wyjście, które jest cały Quine'a wyjątkiem cytatu. Następnie '!ustawia masę atomu na kod znaku !, +zwiększa ją, co daje "i Odrukuje, jednocześnie niszcząc atom. Program kończy się, ponieważ nie ma już atomów.

Martin Ender
źródło
11

Python 2.7, 377 310 304 194 191 bajtów!

To mój pierwszy golf, więc nie spodziewałem się, że będzie zbyt dobry. Ale pomyślałem, że pomysł w rozwiązaniu, które wymyśliłem, był nieco zabawny, więc i tak go publikuję.

def f():
 import threading as T,inspect as i;global t,a,i
 try:t.cancel()
 except:a=0
 a+=1;t=T.Timer(1,d);t.start()
def d():print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")
f()

Rzeczywiście, jest to quine; możesz spróbować tutaj . Dość mocno nadużywa modułu inspekcji.

Jeśli spróbujemy uruchomić go z tym samym kodem źródłowym x2, otrzymamy również odpowiednie wyjście; możesz spróbować tutaj . x3, x4 itp. działają zgodnie z oczekiwaniami.

Nieoznakowany z wyjaśnieniem:

def f():                                   # Defines a central function f
    import threading as T,inspect as i     # Imports threading and inspect
    global t,a,i                           # Global vars
    try:
        t.cancel()                         # Tries to cancel Timer from previous code
    except:
        a = 0                              # Reached when code is 1st copy; initializes a.
    a += 1                                 # a++; this is the number of copies thus far.
    t = T.Timer(1,d)               # Creates, then starts a timer to call function
    t.start()                              # d in 1 second.

def d():                                   # Prints out the source code; the quine part.
    print''.join(c*a for c in i.getsource(f)+i.getsource(d)+"f()")

f()                                        # Calls f()!
Calconym
źródło
Czy to nie jest oszustwo, ponieważ czyta kod źródłowy własnych funkcji za pomocą inspect? (patrz odpowiedni meta post ). W PPCG mamy określone definicje tego, co czyni quine ważną, a „czytanie źródła” jest zwykle uważane za oszustwo.
FlipTack,
@FlipTack Nie jestem pewien, czy sprawdzenie funkcji jest tym samym, co odczytanie kodu źródłowego. Quiny w JavaScript i językach opartych na stosie robią to cały czas.
Dennis
Dobrze :). Dodałem wyróżnianie składni dla twojego postu. Fajny pomysł za pomocą wątków!
FlipTack,
import threading,inspect as imożnaimport threading as T,inspect as i
nedla2004
@FlipTack Ups, dziękuję.
Calconym
3

CJam , 19 bajtów

{]W=s"_~"+T):Te*}_~

Wypróbuj online!

Jak to działa

{               }_~  Define an anonymous code block (function).
                 _~  Push a copy, and execute the copy.
 ]W=                 Wrap the entire stack in an array and select its last element.
                     This discards whatever was on the stack before the original
                     code block, which is needed for subsequent iterations.
    s"_~"+           Cast the code block to string, push "_~", and concatenate.
                     This pushes the stringified source code on the stack.
          T):T       Push T (initially 0), increment it, and save the result in T.
              e*     Repeat each character in the stringified source code T times.
Dennis
źródło
Co ... jak ... tak szybko ... proszę wyjaśnij kod, abyś mógł nauczyć mnie sposobów CJam.
clismique
@ Qwerp-Derp Dodałem wyjaśnienie.
Dennis
3

RProgN , 66 bajtów

Znaczącą białą spacją będzie moja śmierć

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R 

Wyjaśniono

[ "[ %q ] F 0 1 + `0 = `. { 0 m } R " ] F 0 1 + `0 = `. { 0 m } R   #
[                                                                   # Pop whatever is already on the stack, if anything.
  "[ %q ] F 0 1 + `0 = `. { 0 m } R "                               # This string contains basically the entire function.
                                      ] F                           # ] F duplicates the string, and then F formats it, which in this case puts the first string into the second at %q, surrounded by qoutes.
                                          0 1 + `0 =                # I needed an Incrementer, so I chose 0. 0, is conveniently, pre initilized at 0. And because RProgN is horrifying, you can remap the number functions as they're just more variables. So this increments 0 every time the group is called.
                                                     `. { 0 m } R   # Replace each character with itself repeated '0' times. Because '0' is an incrementer, each time the script is called, the amount of times the characters are repeated increase.

Dobry Boże, jestem potworem ...

Wypróbuj online!

ATaco
źródło
Ponadto, chociaż ~["[%q]F01+`0=`.{0m}R"]F01+`0=`.{0m}Rogólnie działa dobrze, nie jest to prawidłowe rozwiązanie, ponieważ nie ma sposobu na replikację znacznika ZSS.
ATaco
2

Perl 5, 107 bajtów

$_=q[$_=q[S];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}];s/S/$_/;$a++;END{s/./$&x$a/eg;print if$a;$a=0}

Nie golfowany:

$_ = '...INSERT_SOURCE_HERE...';      # Standard quine
s/INSERT_SOURCE_HERE/$_;
$a++;                                 # Count the number of repetitions
END {
    s/./$&x$a/eg;                     # Interweave
    print if $a;                      # Print...
    $a=0;                             # ...but only once
}

Wypróbuj online!

Joey Marianer
źródło
2

Python 3 , 122 121 112 bajtów

s='try:from atexit import*;n+=1\nexcept:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])';exec(s);

Wypróbuj online: jedna kopia | dwie kopie | trzy kopie | cztery kopie z automatyczną weryfikacją

Jak to działa

Wykorzystuje to standardową quine Python: Przechowuj kod, który chcesz wykonać w zmiennej (jako ciąg znaków); zawrzeć w tym ciągu trochę logiki, aby wydrukować się, wszystko przed nim i wszystko po nim; następnie wykonaj ten ciąg.

Kod wykonywany za pomocą ciągu s jest następujący.

try:from atexit import*;n+=1
except:n=1;register(lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s])

Pierwszy wiersz bezwarunkowo importuje moduł atexit , który pozwoli nam zarejestrować moduł obsługi wyjścia. Wielokrotna próba zaimportowania tego samego modułu nie wpływa w żaden sposób na skrypt. Następnie próbuje zwiększyć wartość zmiennej n , aby śledzić, ile kopii kodu źródłowego zostało wykonanych.

Drugi wiersz jest wykonywany tylko wtedy, gdy pierwszy zawiera błąd. Tak będzie w pierwszej iteracji, ponieważ n jest wciąż niezdefiniowane. W tym przypadku inicjalizujemy n jako 1 i rejestrujemy lambda, która wykonuje rzeczywistą magię.

Zarejestrowany moduł obsługi wyjścia

lambda:[print(end=c*n)for c in"s=%r;exec(s);"%s]

zostanie wywołany tuż przed zakończeniem programu. Sam lambda tworzy ciąg "s=%r;exec(s);"%s- %rtworzy reprezentację ciąg prawego argumentu ( ów ), który zawiera wszystko pomiędzy apostrofami i samych cytatów - to iteracje nad jej znaków. Dla każdego znaku c po prostu drukujemy n kopii c . Przechodząc c*njako nazwanego argumentu enddo printśrodków, które nie wysuwu wiersza zostaną załączone.

Dennis
źródło
1

CJam , 14 bajtów

{s"_~"+]:.+}_~

Wypróbuj online!

Objaśnienia

{s"_~"+]:.+}_~
{s"_~"+    }_~ Basic quine operator.
       ]:.+    Append each character to corresponding element of the previous result if existed.
jimmy23013
źródło