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 golf golfowy , więc wygrywa najkrótszy program (w bajtach).
!
..."
? Niektóre języki obsługują dwa lub trzy znaki cudzysłowu.Odpowiedzi:
Noodel ,
97 bajtówTa 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
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."Spróbuj:)"
Fragmenty
źródło
e
jest 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:"
"
? (Przepraszam, próbuję się upewnić, że rozumiem, co mówisz). Czy powinienem również usunąć cały tekst w odpowiedzi dotyczącej używaniae
?"
działa, po prostu usunę dyskusję i po prostu użyję"
.Python
23,181152130124122 bajtówWypró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.exec
Jest 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ą
%r
formatowania ciągów, z pewnym dodatkowym kodem, który usuwa dodatkowe cudzysłowy, jeślioct
jest zmieniany.Alternatywna wersja wykorzystująca „cheaty”
exec
ma 126 bajtów i mniej powtarzalny kod:Wypróbuj online!
źródło
StandardML ,
182 176108 bajtówWersja 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
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>"
:i jeden w formie
"<code in quotes>"<code>
: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ążeit
łańcuch zawierający"
,fn x=>
uruchamia anonimową funkcję, biorąc jeden argumentx
, a następnie konkatenujex^it^x^it
i 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^it
koń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ązanyit
. Następniestr(chr 34)^it;
łączy cytat z początkiem łańcucha i ponieważ ponownie nie podano wyraźnego identyfikatora, wynikowy łańcuch"<code>
jest związanyit
. Na koniecprint(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>
identyfikatorait
, alboit
jest sprawiedliwy"
i podajemy własne źródło<code>
jako argument, a zatem musi to być funkcja, która obsługuje taki argument.Aby określić, w którym przypadku jesteśmy, sprawdzamy, czy rozmiar
it
jest większy niż 1. Jeśli nie, toit
jest"
i jesteśmy w drugim przypadku, więcelse
-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 it
jest większy niż 1, jesteśmy w częścithen
i po prostu wykonujemyprint(it^it)
, prawda? Niezupełnie, ponieważ zlekceważyłem powiedzieć, że SML jest mocno wpisany, co oznacza, że warunekif <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ż typelse
części: anonimowa funkcja, która pobiera ciąg znaków, a następnie wywołuje,print
ma typstring -> <return type of print>
iprint
ma typstring -> unit
(unit
jest w pewien sposób podobny dovoid
innych języków), więc typ wynikowy jest ponowniestring -> unit
.Więc jeśli
then
część była właśnieprint(it^it)
tego typuunit
, otrzymalibyśmy błąd niedopasowania typu. Co powiesz nafn _=>print(it^it)
? (_
jest symbolem wieloznacznym dla argumentu, który nie jest używany) Ta anonimowa funkcja sama w sobie ma typ,'a -> unit
gdzie'a
oznacza dowolny typ, więc w kontekście naszego warunku, który wymuszastring -> unit
typ, zadziałałoby. (Zmienna typu'a
jest tworzona z typemstring
.) Jednak w tym przypadku nie wydrukowalibyśmy niczego, ponieważ funkcja anonimowa nigdy nie jest wywoływana! Pamiętaj, że kiedy wchodzimy wthen
-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)
jakothen
-part, drukując najpierw, a następnie zwracając funkcję,print
która ma poprawny typ.źródło
V ,
27, 23 bajtówWypróbuj online!
Ponieważ zawiera on niektóre niedrukowalne znaki, oto wersja do odczytu:
a oto zrzut heksowy:
Pierwszą rzeczą, którą musimy zrobić, to ustalić, czy pierwszy znak jest cytatem.
éP
wstawia znak „P”, ale"éP
jest NOOP. Następnie wykonujemy niewielką modyfikację standardowego przedłużanego quine, który jest:Zrobimy to jednak nieco inaczej. Najpierw musimy wstawić początkowy tekst „éP”. Tak robimy
Oto miejsce rozgałęzienia. Tekst aktualnie w buforze to
Jeśli nie zapakujemy go w cudzysłów, wówczas „P” nigdy nie zostałby wstawiony, a bufor to:
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:źródło
JavaScript (ES6),
239237 bajtówWypróbuj każdą wersję w świeżym środowisku (np. Nowa karta przeglądarki)
Musi istnieć co najmniej jeden sposób na uproszczenie tego ...
źródło