Cytaty bezpieczne

17

Twoje zadanie jest proste: napisz program (lub funkcję), który nie pobiera danych wejściowych i nie wyświetla (lub zwraca) kodu źródłowego. Problem polega na tym, że gdy program jest zawinięty"quotes" (znak Unicode 34), powinien ponownie wygenerować (obecnie cytowany) kod źródłowy.

Obowiązują standardowe zasady dotyczące quines. To jest , więc wygrywa najkrótszy program (w bajtach).

Esolanging Fruit
źródło
8
@ATaco myśl twórczo. Kod w cudzysłowie zwykle nie jest wykonywany, ale gdy cały program jest otoczony cudzysłowami, sekcje te wykonywane.
Pavel
1
Hmm, dobra uwaga.
ATaco
To może współpracować z BF w implementacjach, które wspierają !...
Esolanging Fruit
1
Musisz użyć "? Niektóre języki obsługują dwa lub trzy znaki cudzysłowu.
Neil
1
@tkellehe Meta: Co liczy się jako właściwy quine? O ile rozumiem twój 1-bajtowy quine, narusza on wymagania dotyczące kodu / danych sformułowane w najwyższym głosowaniu.
Laikoni

Odpowiedzi:

4

Noodel , 9 7 bajtów

Ta wersja działa tak samo jak druga, tylko że zapomniałem, że Noodel ma sposób na uruchomienie jednego bloku kodu i stworzyłem język ...

Ḷ1ḥ-Ð1ḥ@€

ḷḥ-Ðḥ@ḅ

Spróbuj:)


Jak to działa

ḷḥ-Ðḥ@ḅ # Single statement that builds itself as a string.
ḷ       # Loop the following block of code unconditionally.
 ḥ-     # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
   Ð    # Push the stack as an array to stdout (since is an array it is done by reference).
    ḥ@  # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
      ḅ # Break out of the given loop. (The stack is now ["ḷ", "ḥ-Ðḥ@ḅ"]).

        # The top of the stack is popped off and displayed which modifies the array to produce {["ḷ"], "ḥ-Ðḥ@ḅ"} in stdout.

Cytat-Bezpieczeństwo

Umieszczanie "znaku przed i po programie działa, ponieważ Noodel ma zestaw znaków poświęcony temu, co nazywam drukowalnymi . Są one natychmiast parsowane jako literały łańcuchowe, gdy są umieszczone same i pozwalają na łatwe wydrukowanie czegoś na ekranie. W przeciwieństwie do większości języków, Noodel widzi normalny zestaw ASCII, który jest uważany za warty wydruku jako bezpośrednie literały łańcuchowe (z wyjątkiem spacji i przesunięcia wiersza), w których cytowanie kodu jest jedynie postrzegane jako naciskanie na łańcuchy.

"ḷḥ-Ðḥ@ḅ"

"         # Pushes on the string literal "\"" onto the stack.

 ḷḥ-Ðḥ@ḅ  # Same execution as before, simply builds the Quine for this loop.
 ḷ        # Loop the following block of code unconditionally.
  ḥ-      # Push the string literal of the token preceding this one which pushes "ḷ" onto the stack.
    Ð     # Push the stack as an array to stdout (since is an array it is done by reference).
     ḥ@   # Push the string literal for this block of code which pushes "ḥ-Ðḥ@ḅ" onto the stack.
       ḅ  # Break out of the given loop. (The stack is now ["\"", "ḷ", "ḥ-Ðḥ@ḅ"]).

        " # Pushes on the string literal "\"" onto the stack.

          # The top of the stack is popped off and displayed which modifies the array to produce {["\"", "ḷ", "ḥ-Ðḥ@ḅ"], "\""} in stdout.

"Spróbuj:)"


Fragmenty

<div id="noodel" code='ḷḥ-Ðḥ@ḅ' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>


<div id="noodel" code='"ḷḥ-Ðḥ@ḅ"' input="" cols="10" rows="1"></div>
<script src="https://tkellehe.github.io/noodel/noodel-latest.js"></script>
<script src="https://tkellehe.github.io/noodel/ppcg.min.js"></script>

tkellehe
źródło
Nie sądzę, że używanie ejest prawidłowe. Pytanie nie wymaga znaku zakodowanego jako bajt 34, ale znak Unicode 34. Bez względu na to, jakiego kodowania używasz, jest tylko jeden:"
Dennis
@Dennis, zgaduję, że mówisz, że odniesienie do znaku Unicode 34 miało na celu upewnienie się, że wszyscy używają tego samego "? (Przepraszam, próbuję się upewnić, że rozumiem, co mówisz). Czy powinienem również usunąć cały tekst w odpowiedzi dotyczącej używania e?
tkellehe 27.01.17
1
Tak, istnieją tysiące kodowań, ale tylko jeden zestaw znaków Unicode. Ponieważ "działa, po prostu usunę dyskusję i po prostu użyję ".
Dennis
11

Python 2 3, 181 152 130 124 122 bajtów

""" """>" "or exec("oct=0");p='"""" """>" "or exec("oct=0");p=%r;a=oct==0;print(p[a:~a]%%p)#".';a=oct==0;print(p[a:~a]%p)#

Wypróbuj online!TIO jest wyposażony w nagłówek i stopkę, które automatycznie testują ważność quine. Możesz je wyczyścić, aby uruchomić quine.

Ten kod działa przy użyciu potrójnych cytatów w Pythonie. """ """jest równe ' 'i"""" """ równy '" '.

Kod używa exec , ale nie do „nie-quiney” sposobu wykonywania danych jako kodu, tylko do ustawiania zmiennej z wnętrza wyrażenia. execJest poprawnie zakodowany w danych, too.

Pierwsza instrukcja porównuje ciąg znaków, być może z wcześniejszym cytatem " ", i ustawia zmiennąoct . (Zmienna mogła być dowolnym krótkim wbudowanym).

Reszta kodu następnie implementuje tradycyjną quinę Pythona za pomocą %rformatowania ciągów, z pewnym dodatkowym kodem, który usuwa dodatkowe cudzysłowy, jeślioct jest zmieniany.

Alternatywna wersja wykorzystująca „cheaty” execma 126 bajtów i mniej powtarzalny kod:

""" """>" "and exec("oct=0");s='"""" """>" "and exec("oct=0");s=%r;p=%r;exec(p)#".';p='a=oct!=0;print(s[a:~a]%(s,p))';exec(p)#

Wypróbuj online!

PurkkaKoodari
źródło
7

StandardML , 182 176 108 bajtów

";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))";str(chr 34)^it;(print(it^it);fn x=>print(x^it^x^it))

Wersja bez cudzysłowu : Wypróbuj na polu kodowania.
Cytowana wersja: Wypróbuj na polu kodowania.

Zauważ, że dane wyjściowe wyglądają mniej więcej tak

> val it = "{some string}" : string
> val it = "{some string}" : string
{output to stdout}> val it = fn : string -> unit

ponieważ kod jest interpretowany deklaracja po deklaracji (każda ;kończy deklarację) i pokazuje wartość i typ każdej deklaracji.


tło

W SML znajduje się quine formy <code>"<code in quotes>":

str(chr 34);(fn x=>print(x^it^x^it))"str(chr 34);(fn x=>print(x^it^x^it))" 

i jeden w formie "<code in quotes>"<code>:

";str(chr 34)^it;print(it^it)";str(chr 34)^it;print(it^it)

Oba opierają się na fakcie, że <code>-part nie zawiera cudzysłowów i dlatego mogą być cytowane bez potrzeby uciekania przed czymkolwiek, "potrzebne do wyprowadzenia quine są podane przezstr(chr 34) .

Opierają się również w dużej mierze na niejawnym identyfikatorze it który jest używany, gdy w deklaracji nie podano wyraźnego identyfikatora.

W pierwszej quine str(chr 34);wiąże itłańcuch zawierający ", fn x=>uruchamia anonimową funkcję, biorąc jeden argument x, a następnie konkatenuje x^it^x^iti wypisuje powstały ciąg. Ta anonimowa funkcja jest bezpośrednio stosowana do ciągu zawierającego kod programu, więc konkatenacja się x^it^x^itkończy <code>"<code>".

Druga quine zaczyna się od samego kodu programu jako łańcucha, z ";str(chr 34)^it;print(it^it)";którym jest związany it. Następnie str(chr 34)^it;łączy cytat z początkiem łańcucha i ponieważ ponownie nie podano wyraźnego identyfikatora, wynikowy łańcuch "<code>jest związany it. Na koniec print(it^it)konkatenuje ciąg z samym sobą, "<code>"<code>co jest następnie drukowane.


Wyjaśnienie

Edytować: Nie jest już na bieżąco z wersją 108-bajtową, jednak można ją również zrozumieć po przeczytaniu tego wyjaśnienia.

Quine-bezpieczny quine łączy oba powyższe podejścia i sam jest w formie "<code>"<code> . Ponowne umieszczenie tego w kwotowaniach daje""<code>"<code>" , więc otrzymujemy pusty ciąg, a następnie quine innej formy.

Oznacza to, że program albo otrzymuje własne źródło w formie "<code>identyfikatora it, albo itjest sprawiedliwy "i podajemy własne źródło <code>jako argument, a zatem musi to być funkcja, która obsługuje taki argument.

(if size it>1then(print(it^it);fn _=>())else fn x=>print(it^it^x^it^x^it))

Aby określić, w którym przypadku jesteśmy, sprawdzamy, czy rozmiar itjest większy niż 1. Jeśli nie, to itjest "i jesteśmy w drugim przypadku, więc else-part zwraca anonimową funkcję, fn x=>print(it^it^x^it^x^it)która jest następnie wywoływana, ponieważ następuje po niej źródło jako ciąg . Zwróć uwagę na wiodące, it^it^które jest potrzebne dla pustego ciągu na początku programu.

Jeśli size itjest większy niż 1, jesteśmy w części theni po prostu wykonujemy print(it^it), prawda? Niezupełnie, ponieważ zlekceważyłem powiedzieć, że SML jest mocno wpisany, co oznacza, że ​​warunek if <cond> then <exp_1> else <exp_2>musi zawsze mieć ten sam typ, co ponownie oznacza, że ​​wyrażenia <exp_1>i <exp_2>muszą mieć ten sam typ. Znamy już typ elseczęści: anonimowa funkcja, która pobiera ciąg znaków, a następnie wywołuje, printma typ string -> <return type of print>i printma typ string -> unit( unitjest w pewien sposób podobny do voidinnych języków), więc typ wynikowy jest ponownie string -> unit.

Więc jeśli thenczęść była właśnie print(it^it)tego typu unit, otrzymalibyśmy błąd niedopasowania typu. Co powiesz na fn _=>print(it^it)? ( _jest symbolem wieloznacznym dla argumentu, który nie jest używany) Ta anonimowa funkcja sama w sobie ma typ, 'a -> unitgdzie 'aoznacza dowolny typ, więc w kontekście naszego warunku, który wymusza string -> unittyp, zadziałałoby. (Zmienna typu 'ajest tworzona z typem string.) Jednak w tym przypadku nie wydrukowalibyśmy niczego, ponieważ funkcja anonimowa nigdy nie jest wywoływana! Pamiętaj, że kiedy wchodzimy w then-part, ogólny kod jest "<code>"<code>taki, że<code> -part ocenia funkcję, ale ponieważ nic po nim nie następuje, nie jest wywoływana.

Zamiast tego używamy sequentialisation który ma postać (<exp_1>; ...; <exp_n>)gdzie <exp_1>się <exp_n-1>może mieć dowolne typy i rodzaj <exp_n>zapewnia typ całej sequentialisation. Z funkcjonalnego punktu widzenia wartości <exp_1>to <exp_n-1>są po prostu odrzucane, jednak SML obsługuje również konstrukty imperatywne, więc wyrażenia mogą mieć skutki uboczne. W skrócie, bierzemy (print(it^it);print)jako then-part, drukując najpierw, a następnie zwracając funkcję, printktóra ma poprawny typ.

Laikoni
źródło
7

V , 27 , 23 bajtów

éPñi"éP241"qpá"lxx|xÿ

Wypróbuj online!

Ponieważ zawiera on niektóre niedrukowalne znaki, oto wersja do odczytu:

éPñi"éP<C-v>241<esc>"qpá"lxx|xÿ

a oto zrzut heksowy:

00000000: e950 f169 22e9 5016 3234 311b 2271 70e1  .P.i".P.241."qp.
00000010: 226c 7878 7c78 ff                        "lxx|x.

Pierwszą rzeczą, którą musimy zrobić, to ustalić, czy pierwszy znak jest cytatem. éPwstawia znak „P”, ale "éPjest NOOP. Następnie wykonujemy niewielką modyfikację standardowego przedłużanego quine, który jest:

ñi<C-v>241<esc>"qpÿ

Zrobimy to jednak nieco inaczej. Najpierw musimy wstawić początkowy tekst „éP”. Tak robimy

ñ                        " Start recording into register 'q'
 i                       " Enter insert mode
  "éP<C-v>241<esc>       " Enter the following text: '"éPñ'
                  "qp    " Paste the text in register 'q'
                     á"  " Append a '"'

Oto miejsce rozgałęzienia. Tekst aktualnie w buforze to

"éPñi"éP<C-v>241<esc>"qpá"P
Cursor is here ----------^

Jeśli nie zapakujemy go w cudzysłów, wówczas „P” nigdy nie zostałby wstawiony, a bufor to:

"éPñi"éP<C-v>241<esc>"qpá"
Cursor is here ----------^

Ponieważ nadal nagrywamy, możemy robić, co tylko zechcemy, a gdy to się stanie, zostanie dodane do bufora "qp. Od tego momentu warunkowo można usunąć cytaty:

l           " Move one character to the right. If there is no character to the right, 
            " then this is effectively a "break" statement, stopping playback of the recording
 xx         " Delete two characters (the '"P')
   |        " Move to the first character on this line
    x       " Delete one character
     ÿ      " End the program
James
źródło
3

JavaScript (ES6), 239 237 bajtów

Set=``;eval(";a='Set=``;eval(~;a=1;S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);~)';S=String.fromCharCode;q=S(34);r=Set&&q;s=S(39);alert(r+a.replace(/[^ -}]/g,q).replace(1,s+a+s)+r);")

Wypróbuj każdą wersję w świeżym środowisku (np. Nowa karta przeglądarki)

Musi istnieć co najmniej jeden sposób na uproszczenie tego ...

ETHprodukcje
źródło
1
Przypuszczam, że możesz użyć tablicy dla zamienników w taki sposób: [x = "replace"]. Mogę coś zepsuć, nie mam zbyt dużego doświadczenia z quinesami ...
Luke