var QUESTION_ID=69;
var OVERRIDE_USER=98;
var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk";var answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(index){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}
function commentUrl(index,answers){return"https://api.stackexchange.com/2.2/answers/"+answers.join(';')+"/comments?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}
function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(data){answers.push.apply(answers,data.items);answers_hash=[];answer_ids=[];data.items.forEach(function(a){a.comments=[];var id=+a.share_link.match(/\d+/);answer_ids.push(id);answers_hash[id]=a});if(!data.has_more)more_answers=!1;comment_page=1;getComments()}})}
function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(data){data.items.forEach(function(c){if(c.owner.user_id===OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c)});if(data.has_more)getComments();else if(more_answers)getAnswers();else process()}})}
getAnswers();var SCORE_REG=(function(){var headerTag=String.raw `h\d`
var score=String.raw `\-?\d+\.?\d*`
var normalText=String.raw `[^\n<>]*`
var strikethrough=String.raw `<s>${normalText}</s>|<strike>${normalText}</strike>|<del>${normalText}</del>`
var noDigitText=String.raw `[^\n\d<>]*`
var htmlTag=String.raw `<[^\n<>]+>`
return new RegExp(String.raw `<${headerTag}>`+String.raw `\s*([^\n,]*[^\s,]),.*?`+String.raw `(${score})`+String.raw `(?=`+String.raw `${noDigitText}`+String.raw `(?:(?:${strikethrough}|${htmlTag})${noDigitText})*`+String.raw `</${headerTag}>`+String.raw `)`)})();var OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(a){return a.owner.display_name}
function process(){var valid=[];answers.forEach(function(a){var body=a.body;a.comments.forEach(function(c){if(OVERRIDE_REG.test(c.body))
body='<h1>'+c.body.replace(OVERRIDE_REG,'')+'</h1>'});var match=body.match(SCORE_REG);if(match)
valid.push({user:getAuthorName(a),size:+match[2],language:match[1],link:a.share_link,})});valid.sort(function(a,b){var aB=a.size,bB=b.size;return aB-bB});var languages={};var place=1;var lastSize=null;var lastPlace=1;valid.forEach(function(a){if(a.size!=lastSize)
lastPlace=place;lastSize=a.size;++place;var answer=jQuery("#answer-template").html();answer=answer.replace("{{PLACE}}",lastPlace+".").replace("{{NAME}}",a.user).replace("{{LANGUAGE}}",a.language).replace("{{SIZE}}",a.size).replace("{{LINK}}",a.link);answer=jQuery(answer);jQuery("#answers").append(answer);var lang=a.language;lang=jQuery('<i>'+a.language+'</i>').text().toLowerCase();languages[lang]=languages[lang]||{lang:a.language,user:a.user,size:a.size,link:a.link,uniq:lang}});var langs=[];for(var lang in languages)
if(languages.hasOwnProperty(lang))
langs.push(languages[lang]);langs.sort(function(a,b){if(a.uniq>b.uniq)return 1;if(a.uniq<b.uniq)return-1;return 0});for(var i=0;i<langs.length;++i)
{var language=jQuery("#language-template").html();var lang=langs[i];language=language.replace("{{LANGUAGE}}",lang.lang).replace("{{NAME}}",lang.user).replace("{{SIZE}}",lang.size).replace("{{LINK}}",lang.link);language=jQuery(language);jQuery("#languages").append(language)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654"> <div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table>
Odpowiedzi:
Sześciokąty , długość boku
1716,816705 bajtówWypróbuj online!
Oto jak wygląda rozwinięta:
Ah dobrze, to było dość emocjonalny rollercoaster ... Przestałem liczyć ile razy przeszedłem między „haha, to szaleństwo” i „czekaj, czy ja to powinna ona być w rzeczywistości dość wykonalne”. Ograniczenia nałożone na kod przez reguły układu Hexagony były ... poważne.
Możliwe jest zmniejszenie długości boku o 1 lub 2 bez zmiany ogólnego podejścia, ale będzie to trudne (tylko komórki z
#
są obecnie nieużywane i dostępne dla dekodera). W tej chwili nie mam też absolutnie żadnych pomysłów na bardziej efektywne podejście, ale jestem pewien, że takie istnieje. Zastanowię się nad tym przez kilka następnych dni i może spróbuję zagrać w golfa z boku, zanim dodam wyjaśnienie i wszystko.Przynajmniej udowodniłem, że to możliwe ...
Niektóre skrypty CJam dla własnego odniesienia:
źródło
!
a następnie za pomocą lustro/
w 2. ostatnim wierszu wchodzi do dekodera, aby wydrukować kod dekodera, aby zakończyć quine. Ma to cudowne zastosowanie<
i>
odczytuje wielowierszową bardzo dużą liczbę całkowitą i buduje obszar do przechowywania dekodera. Naprawdę chciałbym wiedzieć, jakie „dziesiątki podejść” są brane pod uwagę?MySQL, 167 znaków
Zgadza się. :-)
Naprawdę sam to napisałem. Został pierwotnie opublikowany na mojej stronie .
źródło
GolfScript, 2 bajty
(uwaga kończąca nowy wiersz) Spycha liczbę 1 na stos. Na końcu programu GolfScript drukuje wszystkie elementy na stosie (bez spacji między nimi), a następnie drukuje nowy wiersz.
To jest prawdziwa quine (jak podano w pytaniu), ponieważ faktycznie wykonuje kod; nie tylko „odczytuje plik źródłowy i drukuje go” (w przeciwieństwie do przesyłania PHP).
Dla innego przykładu, oto program GolfScript do wydrukowania
12345678
:9
: pchnij 9 na stos,
: zużyj 9 jako argument, pchnij tablicę[0 1 2 3 4 5 6 7 8]
na stos(
: używaj tablicy jako argumentu, wsuń tablicę[1 2 3 4 5 6 7 8]
i element0
na stos;
: odrzuć najwyższy przedmiot ze stosuStos zawiera teraz tablicę
[1 2 3 4 5 6 7 8]
. Zostanie to zapisane na standardowe wyjście, bez spacji między elementami, a następnie nowy wiersz.źródło
1
nie jest quine w GolfScript: wypisuje1\n
, gdzie\n
oznacza nową linię. Jednak program dwóch znaków1\n
jest quine.\n
prawdopodobnie też jest?Brain-Flak ,
9,8e5801,3e5629,3e51612818110244452433242404200418038523656361635402485 + 3 = 2488 bajtówTeraz mieści się w obserwowalnym wszechświecie!
Wypróbuj online!
Wyjaśnienie
Quine działa jak większość Quines w językach ezoterycznych; ma dwie części: enkoder i dekoder. Koder zawiera wszystkie nawiasy na początku, a dekoder jest bardziej złożoną częścią na samym końcu.
Naiwnym sposobem kodowania programu byłoby umieszczenie wartości ASCII każdego znaku w dekoderze na stosie. To nie jest zbyt dobry pomysł, ponieważ Brain-Flak używa tylko 8 znaków (
()<>[]{}
), więc w końcu płacisz sporo bajtów, aby zakodować bardzo mało informacji. Mądrzejszym i dotychczas stosowanym jest przypisanie każdego z 8 nawiasów klamrowych do znacznie mniejszej liczby (1-8) i przekonwertowanie ich na wartości ASCII za pomocą naszego dekodera. Jest to miłe, ponieważ kodowanie znaku kosztuje nie więcej niż 18 bajtów, w przeciwieństwie do wcześniejszych 252.Jednak ten program nie działa. Opiera się na fakcie, że wszystkie programy Brain-Flak są zbalansowane do kodowania 8 nawiasów klamrowych z liczbami do 5. Koduje je w następujący sposób.
Wszystkie zamknięte nawiasy klamrowe mają przypisaną wartość 1, ponieważ możemy użyć kontekstu, aby określić, którego z nich musimy użyć w danym scenariuszu. Może to zabrzmieć jak zniechęcające zadanie dla programu Brain-Flak, ale tak naprawdę nie jest. Weźmy na przykład następujące kodowanie z odkodowanymi otwartymi nawiasami klamrowymi i zamienionymi nawiasami klamrowymi na
.
:Mam nadzieję, że widać, że algorytm jest dość prosty, czytamy od lewej do prawej, za każdym razem, gdy napotykamy otwarty nawias klamrowy, przesuwamy jego wąski nawias klamrowy do wyimaginowanego stosu, a gdy napotkamy wartość
.
nawijamy najwyższą wartość i umieszczamy ją w miejscu.
. To nowe kodowanie oszczędza nam ogromną liczbę bajtów w koderze, tracąc jedynie garść bajtów w dekoderze.Objaśnienie niskiego poziomu
Praca w toku
źródło
Preludium ,
51574514234817611537664569535423241214184178175169148142136133 bajtówDzięki Sp3000 za oszczędność 3 bajtów.
To jest dość długie ...(dobra, wciąż jest długie ... przynajmniej pokonuje najkrótsząznaną BrainfuckC # quine w tym wyzwaniu), ale jest to pierwsza quine, którą sam odkryłem (moje zgłoszenia Lua i Julii są tak naprawdę tłumaczeniami standardowych technik quine na inne języki) i, o ile mi wiadomo, do tej pory nikt nie napisał quine w Preludium, więc jestem z tego naprawdę dumny. :)Ta duża liczba cyfr to tylko kodowanie kodu podstawowego, dlatego quine jest tak długi.
Cyfry kodujące quine zostały wygenerowane za pomocą tego skryptu CJam .
Wymaga to zgodnego ze standardami interpretera, który drukuje znaki (używając wartości jako kodów znaków). Więc jeśli używasz interpretera Python , musisz ustawić
NUMERIC_OUTPUT = False
.Wyjaśnienie
Po pierwsze, kilka słów o Preludium: każda linia w Preludium jest osobnym „głosem”, który manipuluje własnym stosem. Te stosy są inicjowane do nieskończonej liczby zer. Program jest wykonywany kolumna po kolumnie, gdzie wszystkie polecenia w kolumnie są wykonywane „jednocześnie” na podstawie poprzednich stanów stosu. Cyfry są wypychane na stos indywidualnie, więc
42
popchną a4
, a następnie a2
. Nie ma możliwości bezpośredniego wypychania większych liczb, musisz je dodać. Wartości można skopiować z sąsiednich stosów za pomocąv
i^
. Pętle w stylu Brainfuck można wprowadzić w nawiasach. Zobacz link w nagłówku, aby uzyskać więcej informacji.Oto podstawowa idea quine: najpierw pchamy ładunki cyfr na stos kodujący rdzeń quine. Wspomniany rdzeń następnie pobiera te cyfry, dekoduje je w celu wydrukowania, a następnie drukuje cyfry w postaci, w jakiej pojawiają się w kodzie (i na końcu
)
).Jest to nieco skomplikowane przez fakt, że musiałem podzielić rdzeń na wiele linii. Początkowo miałem kodowanie na początku, ale potem musiałem uzupełnić pozostałe wiersze taką samą liczbą spacji. Właśnie dlatego początkowe wyniki były tak duże. Teraz umieściłem kodowanie na końcu, ale oznacza to, że najpierw muszę pominąć rdzeń, a następnie przesunąć cyfry i wskoczyć z powrotem na początek i wykonać drukowanie.
Kodowanie
Ponieważ kod ma tylko dwa głosy, a przyleganie jest cykliczne
^
iv
jest synonimem. To dobrze, ponieważv
ma jak dotąd największy kod znakowy, więc unikanie go zawsze przy użyciu^
ułatwia kodowanie. Teraz wszystkie kody znaków mieszczą się w zakresie od 10 do 94 włącznie. Oznacza to, że mogę zakodować każdy znak dokładnie dwoma cyframi dziesiętnymi. Jest jednak jeden problem: niektóre znaki, zwłaszcza linia, mają zero w reprezentacji dziesiętnej. Jest to problem, ponieważ zer nie można łatwo odróżnić od dolnej części stosu. Na szczęście istnieje proste rozwiązanie tego problemu: wyrównujemy kody znaków2
, więc mamy zakres od 12 do 96 włącznie, który nadal wygodnie mieści się w dwóch cyfrach dziesiętnych. Teraz ze wszystkich znaków, które mogą pojawić się w programie Preludium,0
ma 0 w swojej reprezentacji (50), ale tak naprawdę wcale nie potrzebujemy0
. Więc takiego kodowania używam, wypychając każdą cyfrę z osobna.Ponieważ jednak pracujemy ze stosem, reprezentacje są wypychane w odwrotnej kolejności. Więc jeśli spojrzysz na koniec kodowania:
Podziel na pary i odwróć, następnie odejmij dwa, a następnie wyszukaj kody znaków:
gdzie
32
odpowiada spacjom. Rdzeń wykonuje dokładnie tę transformację, a następnie drukuje znaki.Rdzeń
Spójrzmy więc, jak te liczby są faktycznie przetwarzane. Po pierwsze, należy zauważyć, że pasujące nawiasy nie muszą znajdować się w tej samej linii w Preludium. Może istnieć tylko jeden nawias na kolumnę, więc nie ma dwuznaczności, w której nawiasy należą do siebie. W szczególności pionowe położenie nawiasu zamykającego jest zawsze nieistotne - stos, który jest sprawdzany w celu ustalenia, czy pętla się kończy (lub jest całkowicie pomijany), zawsze będzie tym, który ma
(
.Chcemy uruchomić kod dokładnie dwa razy - za pierwszym razem pomijamy rdzeń i wypychamy wszystkie liczby na końcu, za drugim razem uruchamiamy rdzeń. W rzeczywistości, po uruchomieniu rdzenia, ponownie wypchniemy wszystkie te liczby, ale ponieważ pętla kończy się później, nie ma to znaczenia. To daje następujący szkielet:
Najpierw wciskamy a
7
na pierwszy głos - jeśli tego nie zrobimy, nigdy nie wejdziemy w pętlę (dla szkieletu ważne jest tylko, że nie jest to zero ... dlaczego konkretnie7
zobaczymy później) . Następnie wchodzimy do głównej pętli. Teraz drugi głos zawiera kolejną pętlę. Przy pierwszym przejściu pętla zostanie pominięta, ponieważ drugi stos jest pusty / zawiera tylko 0. Skaczemy więc prosto do kodowania i wypychamy wszystkie te cyfry na stos.7
Nam nasunąć pierwszego stosu nadal istnieje, więc powtarza pętlę.Tym razem jest też
7
na drugim stosie, więc wchodzimy w pętlę na drugim głosie. Pętla drugiego głosu jest tak zaprojektowana, że stos jest znowu pusty na końcu, więc działa tylko raz. Będzie ona również wyczerpywać pierwszego stosu ... Więc kiedy wyjeżdżamy pętlę na drugim głosem, ponownie wcisnąć wszystkie cyfry, ale teraz7
na pierwszym stosie została odrzucona, więc główne końce pętli i program kończy.Następnie spójrzmy na pierwszą pętlę w rzeczywistym rdzeniu. Robienie rzeczy jednocześnie z
(
lub)
jest dość interesujące. Tutaj zaznaczyłem korpus pętli=
:Oznacza to, że kolumna zawierająca
(
nie jest uważana za część pętli (znaki tam wykonywane są tylko raz, nawet jeśli pętla zostanie pominięta). Ale kolumna zawierająca)
jest częścią pętli i jest uruchamiana raz na każdej iteracji.Zaczynamy od jednego
-
, który zmienia7
pierwszy stos w-7
... znowu, więcej o tym później. Co do faktycznej pętli ...Pętla trwa, dopóki stos cyfr nie został opróżniony. Przetwarza dwie cyfry jednocześnie. Celem tej pętli jest dekodowanie kodowania, wydrukowanie znaku i jednoczesne przesunięcie stosu cyfr na pierwszy głos. Więc ta część pierwsza:
Pierwsza kolumna przenosi cyfrę o 1 głos na pierwszy głos. Druga kolumna kopiuje 10 cyfr na pierwszy głos, jednocześnie kopiując 1 cyfrę z powrotem na drugi głos. Trzecia kolumna przenosi tę kopię z powrotem do pierwszego głosu. Oznacza to, że pierwszy głos ma teraz 1 cyfrę dwa razy, a 10 cyfr pomiędzy. Drugi głos ma tylko kolejną kopię 10-cyfrowej. Oznacza to, że możemy pracować z wartościami na wierzchach stosów i mieć pewność, że na pierwszym stosie pozostaną dwie kopie na później.
Teraz odzyskujemy kod znaków z dwóch cyfr:
Dno to mała pętla, która zmniejsza dziesięciocyfrową liczbę do zera. Do każdej iteracji chcemy dodać 10 na górę. Pamiętaj, że pierwszy
2
nie jest częścią pętli, więc ciało pętli faktycznie+8+2
dodaje 10 (używając2
wcześniej wypychanego), a wypycha kolejne 2. Więc kiedy skończymy z pętlą, pierwszy stos faktycznie ma podstawę 10 wartości i kolejne 2. Odejmujemy 2 z,-
aby uwzględnić przesunięcie w kodowaniu i drukujemy znak za pomocą!
. Po#
prostu odrzuca zero na końcu dolnej pętli.Po zakończeniu tej pętli drugi stos jest pusty, a pierwszy stos przechowuje wszystkie cyfry w odwrotnej kolejności (i a
-7
na dole). Reszta jest dość prosta:Jest to druga pętla rdzenia, która teraz drukuje wszystkie cyfry. Aby to zrobić, musimy wpisać 48 do każdej cyfry, aby uzyskać poprawny kod znaku. Robimy to za pomocą prostej pętli, która uruchamia
8
czasy i dodaje za6
każdym razem. Wynik jest drukowany za pomocą,!
a8
na końcu jest do następnej iteracji.A co z
-7
? Tak,48 - 7 = 41
który jest kodem postaci)
. Magia!Wreszcie, kiedy skończymy z tą pętlą, odrzucamy tę,
8
którą właśnie nacisnęliśmy#
, aby upewnić się, że zostawiamy zewnętrzną pętlę na drugim głosie. Naciskamy ponownie wszystkie cyfry, a program się kończy.źródło
Sześciokąt , długość boku 11, 314 bajtów
Wypróbuj online!
Starsza wersja:
Sześciokąt , długość boku 11, 330 bajtów
Wypróbuj online!
Enkoder: Wypróbuj online!
Program jest mniej więcej równoważny z tym kodem Python: Wypróbuj online!
Rozłożony kod:
Dwa
.
s zajmuje 1 bit. Wszelkie inne znaki wymagają 1 bitu i cyfry podstawowej 97.Wyjaśnienie
Kliknij na zdjęcia, aby powiększyć. Każda część objaśnienia ma odpowiedni kod Pythona, który pomaga zrozumieć.
Część danych
Zamiast skomplikowanej strukturze stosowanych w niektórych innych odpowiedzi (z
<
,"
i kilka innych rzeczy), po prostu niech IP przechodzą przez dolną połowę.Po pierwsze, adres IP przebiega przez wiele liczb, no-op's (
.
) i mirrors (\
). Każda cyfra dołącza się do liczby w pamięci, więc na koniec wartość pamięci jest równa liczbie na początku programu.!
drukuje to,i
$
skacze przez następne>
.Począwszy od
<
. Jeśli wartość pamięcimem
jest fałszywa (<= 0
tzn. Warunekmem > 0
nie jest spełniony), zakończyliśmy drukowanie programu i powinniśmy wyjść. Adres IP podążałby górną ścieżką.(pozwól, aby adres IP działał na
całym świeciedla około 33 poleceń przed naciśnięciem przycisku@
(co kończy program), ponieważ umieszczenie go w dowolnym miejscu powoduje dodatkowe bajty)Jeśli to prawda, podążamy niższą ścieżką, zostajemy przekierowani kilka razy i wykonujemy jeszcze kilka poleceń, zanim trafimy na inny warunek.
Teraz pamięć wygląda następująco:
Jeśli wartość jest prawdziwa:
wykonywany jest następujący kod:
Zobacz szczegółowe wyjaśnienie
Q4
co MartinEnder za HelloWorld Hexagony odpowiedź . Krótko mówiąc, ten kod jest drukowany.
dwukrotnie.Pierwotnie planowałem, aby to
.
raz wydrukować . Kiedy wymyśliłem to (wydrukowałem.
dwa razy) i wdrożyłem, zapisano około 10 cyfr.Następnie,
Oto ważny fakt, z którego zdałem sobie sprawę, że zapisałem mi około 14 cyfr: Nie musisz być w miejscu, w którym zacząłeś.
Aby zrozumieć, co mówię, posłuchajmy analogii BF. (pomiń to, jeśli już zrozumiałeś)
Biorąc pod uwagę kod
Zakładając, że możemy
a
być wartością bieżącej komórki ib
być wartością prawej komórki, proste tłumaczenie tego na BF to:Pamiętaj jednak, że nie musimy być cały czas w tej samej pozycji podczas programu. Możemy pozwolić, aby wartość
a
była tym, czym jesteśmy na początku każdej iteracji, a następnie mamy ten kod:który jest kilka bajtów krótszy.
Ponadto zachowanie zawijania narożników również chroni mnie przed
\
lustrem - bez niego nie byłbym w stanie dopasować cyfr (+2 cyfry dla\
siebie i +2 cyfry dla niesparowanego.
po prawej stronie, nie wspominając o flagi)(Detale:
\
co to odzwierciedla, teraz idzie prosto do góry)
Jeśli wartością (powyższej operacji mod 2) jest fałsz (zero), wówczas podążamy następującą ścieżką:
Nie wyjaśnię tutaj zbyt szczegółowo, ale przesunięcie nie jest właściwie dokładne
33
, ale jest zgodne z33
modem256
. Ichr
ma niejawny charakter% 256
.źródło
Vim, 11 bajtów
iq"qP<Esc>
: Ręcznie wstaw duplikat tekstu, który musi znajdować się poza nagraniem.q"
ihqP
: Zapisz wnętrze bezpośrednio w""
rejestrze bez nazwy , aby można je było wkleić na środku. Jesth
to jedyne wymagane repozycjonowanie; jeśli umieścisz go w makrze, zostanie wklejony do wyniku.Edytować
Uwaga na temat nagrywania za pomocą
q"
: Rejestr bezimienny""
jest zabawną rzeczą. To nie jest tak naprawdę rejestr, jak inne, ponieważ tam nie ma tekstu. W rzeczywistości jest to wskaźnik do innego rejestru (zwykle"-
do usuwania bez nowej linii,"0
do yanków lub"1
do usuwania z nową linią).q"
łamie zasady; tak naprawdę pisze"0
. Jeśli""
wskazywałeś już na inny rejestr"0
,q"
nadpisze,"0
ale pozostawi""
bez zmian. Kiedy zaczynasz świeżego Vima,""
automatycznie wskazuje na"0
, więc w takim razie nic ci nie jest.Zasadniczo Vim jest dziwny i pełen błędów.
źródło
y
lub coś przed biegiem może pomóc␛
do pokazywania naciśnięcia klawisza <Esc>? Część tego „Kontrolnego<Esc>
Notacja jest standardem w mapowaniach Vima (:help <>
) i właśnie tego używa vimgolf.com. Każdy doświadczony vimgolfer zostanie przyzwyczajony do czytania. Jeśli chodzi o Unicode, muszę zmrużyć oczy, aby przeczytać małe litery, a one zaciemniają metodę pisania ich i przeszukiwania pliku pomocy.Cubix , 20 bajtów
Prawie dostałem
\o/
...Netto :
Wypróbuj online
Wypróbuj tutaj !
Dodatkowe uwagi
Opowieść w tle
Po pod wrażeniem przeczytania tej świetnej odpowiedzi przez @ ais523, zacząłem myśleć o dalszym graniu w golfa. W końcu było tam sporo no-op, a to nie wydawało się bardzo skompresowane. Ponieważ jednak technika, której używa jego odpowiedź (i moja), wymaga, aby kod obejmował całe linie, potrzebna była oszczędność co najmniej 12 bajtów. W jego wyjaśnieniu była jedna uwaga, która sprawiła, że pomyślałem:
Nagle, gdy wstałem i odszedłem po coś do picia, uderzyło mnie: co, jeśli program nie używałby kodów znaków, a raczej liczb reprezentujących górną twarz? Jest to szczególnie krótkie, jeśli drukowany numer ma 2 cyfry. Cubix posiada 3-bajtowych instrukcji jeden za popychanie numery dwucyfrowe:
N
,S
iQ
, które popychają10
,32
a34
odpowiednio, więc to powinno być dość Golfy, pomyślałem.Pierwszą komplikacją związaną z tym pomysłem jest to, że górna twarz jest teraz wypełniona bezużytecznymi liczbami, więc nie możemy już tego używać. Drugą komplikacją jest to, że górna powierzchnia ma rozmiar, który jest kwadratem wielkości kwadratu, i musiał mieć parzysty rozmiar, w przeciwnym razie jedna liczba skończyłaby się również w pozycji początkowej wskaźnika instrukcji, prowadząc do zanieczyszczonego stosu. Z powodu tych komplikacji mój kod musiał zmieścić się na kostce wielkości 2 (która może zawierać „tylko” 24 bajty, więc musiałem grać w golfa co najmniej 21 bajtów). Ponieważ górne i dolne ściany są bezużyteczne, miałem tylko 16 bajtów efektywnych.
Zacząłem więc od wybrania liczby, która stanie się połową górnej części twarzy. Zacząłem od
N
(10), ale to nie do końca zadziałało z powodu podejścia, które podjąłem, aby wydrukować wszystko. Tak czy inaczej, zacząłem od nowa iS
z jakiegoś powodu użyłem (32). To dało właściwy quine, a przynajmniej tak mi się wydawało. Wszystko działało bardzo dobrze, ale brakowało cytatów. Potem przyszło mi do głowy, żeQ
przyszło (34) będzie naprawdę przydatny. W końcu 34 to kod znakowy podwójnego cudzysłowu, który pozwala nam zachować go na stosie, oszczędzając (2, w stosowanym wówczas układzie) cenne bajty. Po tym, jak nieco zmieniłem trasę IP, pozostało mi tylko ćwiczenie, aby wypełnić puste pola.Jak to działa
Kod można podzielić na 5 części. Przejrzę je jeden po drugim. Zauważ, że środkowe ściany kodujemy w odwrotnej kolejności, ponieważ model stosu jest wprowadzany jako ostatni na końcu.
Krok 1: Drukowanie górnej powierzchni
Nieistotne instrukcje zostały zastąpione przez no-ops (
.
). IP rozpoczyna trzecią linię, po lewej stronie, skierowaną na wschód. Stos jest (oczywiście) pusty.IP kończy się na skrajnej lewej pozycji czwartej linii, wskazując na zachód, i ma zamiar zawinąć się do skrajnej prawej pozycji na tej samej linii. Wykonywane instrukcje to (bez znaku przepływu sterującego):
Stos zawiera tylko 34, reprezentujących ostatni znak źródła.
Krok 2: Zakoduj czwartą linię
Ten kawałek właściwie robi to, czego się spodziewasz: koduje czwartą linię. IP zaczyna się od podwójnego cudzysłowu na końcu tego wiersza i idzie na zachód, wypychając kody znaków każdego znaku, na którym wyląduje, aż znajdzie pasujące podwójne cudzysłowy. Ten pasujący podwójny cudzysłów jest także ostatnim znakiem w czwartym wierszu, ponieważ IP zawija się ponownie, gdy osiągnie lewą krawędź.
W efekcie adres IP przesunął się o jedną pozycję w lewo, a stos zawiera teraz reprezentację czwartej linii w kodach znaków i w odwrotnej kolejności.
Krok 3: Wciśnij kolejny cytat
Musimy przekazać kolejny cytat i czy jest lepszy sposób niż recykling
Q
na początku programu, podchodząc do niego z prawej strony? Ma to dodatkową zaletę, że adres IP bezpośrednio trafia do cytatu, który koduje trzecią linię.Oto wersja netto dla tego kroku. Nieistotne intruzje zostały ponownie zastąpione przez no-ops, wykonywane no-op zostały zastąpione hashtagami (
#
) w celach ilustracyjnych, a adres IP zaczyna się od ostatniego znaku w czwartym wierszu.Adres IP kończy się na trzeciej linii przy pierwszej instrukcji, która ma się owinąć na końcu tej linii, ponieważ wskazuje na zachód. Wykonano następujące instrukcje (z wyłączeniem przepływu kontrolnego):
Ten podwójny cytat reprezentuje ten na końcu trzeciego wiersza.
Krok 4: Kodowanie trzeciej linii
Działa to dokładnie tak samo jak w kroku 2, więc poszukaj tam wyjaśnienia.
Krok 5: Wydrukuj stos
Stos zawiera teraz czwartą i trzecią linię, w odwrotnej kolejności, więc wszystko, co musimy teraz zrobić, to wydrukować. IP zaczyna się od przedostatniej instrukcji na trzeciej linii, przesuwając się na zachód. Oto odpowiednia część kostki (ponownie, nieistotne części zostały zastąpione przez brak operacji).
Jest to pętla, jak można się było spodziewać / oczekiwać. Główny korpus to:
Pętla kończy się, jeśli najwyższy element ma wartość 0, co dzieje się tylko wtedy, gdy stos jest pusty. Jeśli pętla się kończy,
@
wykonuje się, kończąc program.źródło
JavaScript ES6 - 21 bajtów
Nazywam to quine „Bling Quine”.
Czasami musisz grać w golfa w dobrym stylu.
źródło
!$=_=>`!$=${$}()`()
oszczędzasz 2 bajty?Invalid assignment left hand side
. Chciałbym, żeby to zadziałało :(Array.prototype.join
.alert
lubconsole.log
po funkcji strzałki i zawijanie ciągu szablonu w nawiasach byłoby skuteczne.Brainf * ck (755 znaków)
Jest to oparte na technice opracowanej przez Erika Bosmana (ejbosman at cs.vu.nl). Zwróć uwagę, że „ESultanik's Quine!” tekst jest rzeczywiście niezbędny, aby był quine!
źródło
ESultanik's Quine!
konfiguruje pamięć jako kodowanie stosuESultanik's Quine!
i dalej, z dwoma bajtami pamięci dla każdego znaku (przesunięcie wartości ASCII od 0x1F). Ostatni bit kodu zapętla się w pamięci, najpierw programowo odtwarzając++>+++…
kody dla każdego znaku, a następnie drukując znaki.Sześciokąt , długość boku
15 14 1312,616 533 456383 bajtówPo kilku dniach ostrożnej gry w golfa, przestawiania pętli i rozpoczynania od nowa, w końcu udało mi się sprowadzić do bocznego sześciokąta.
Wypróbuj online!
Rozłożony:
Chociaż nie wygląda na najbardziej golfowy kod Hexagony, zastosowany przeze mnie rodzaj kodowania jest zoptymalizowany pod kątem dłuższych serii no-ops, czego w innym przypadku byś uniknął.
Wyjaśnienie
To bije poprzednią odpowiedź Hexagony , kodując no-ops (
.
) w inny sposób. Podczas gdy ta odpowiedź oszczędza miejsce, czyniąc każdą inną postać a.
, moja koduje liczbę braków operacji . Oznacza to również, że źródło nie musi być tak ograniczone.Tutaj używam kodowanie base 80, gdzie numery poniżej 16 wskazują działa No-OPS, a numery od 16 do 79 stanowią szereg 32 (
!
) do 95 (_
) (Ja tylko teraz realizującego ja grałem wszystkie_
s z mojego kod lol). Niektóre pseudokod w języku Python:Liczba jest zakodowana w pierwszej połowie sześciokąta, wraz ze wszystkimi znakami
po lewej stronie i
po prawej stronie przekierowując wskaźnik, aby zakodować liczbę w jednej komórce. To pochodzi z odpowiedzi Martina Endera (dzięki), ponieważ nie mogłem wymyślić bardziej efektywnego sposobu.
Następnie wchodzi do dolnej sekcji przez
->
:!
wypisuje numer i'
przechodzi do właściwej komórki pamięci przed rozpoczęciem pętli.P='%
modyfikuje bieżącą liczbę o 80. Jeśli wynikiem jest 0, przejdź do zakończenia@
, w przeciwnym razie zejdź w dół i utwórz komórkę obok wyniku modyfikacji z wartością-16
.Ustaw komórkę na (wartość mod + -16). Jeśli ta wartość jest ujemna, przejdź na rozgałęzienie
>+'\
, w przeciwnym razie zejdź na dół.Jeśli wartość jest dodatnia:
Wskaźnik kończy się na tym,
;-<
co ustawia komórkę na (wartość mod - -16) i drukuje ją.Wartość jest ujemna:
Zejdź do
> ) <
sekcji, która rozpoczyna pętlę. Tutaj jest izolowany:Który wykonuje kod,
'Q4;="=
który wypisuje.
(dzięki ponownie Martin Ender, który napisał program do znajdowania kombinacji liter i cyfr dla znaków) i wraca do początkowej komórki. Następnie zwiększa ()
) komórkę wartości mod i zapętla ponownie, aż wartość mod będzie dodatnia.Po wykonaniu tej czynności przesuwa się w górę i łączy z inną sekcją w:
Wskaźnik ponownie wraca na początek większej pętli
Wykonuje się,
='=:'
która dzieli bieżącą liczbę przez 80 i przechodzi do właściwej komórki.Stara wersja (długość boku 13)
Wypróbuj online!
Zdecydowanie mogę grać w golfa z innej strony, ale muszę to zostawić do jutra, bo robi się późno.Okazuje się, że jestem niecierpliwy i nie mogę się doczekać jutra.Może można grać w golfa z drugiej strony?:(ahhhhhhhh zrobiłem to!Grałem nawet w kilka dodatkowych cyfr z kodowaniem bazowym 77, ale to naprawdę nie ma znaczenia, ponieważ ma tę samą liczbę bajtów.
źródło
PostScript, 20 znaków
Krótki i legalny. 20 znaków, w tym końcowy znak nowej linii.
źródło
Cubix , 45 bajtów
Możesz przetestować ten kod tutaj .
Ten program jest dość trudny do naśladowania, ale aby mieć na to szansę, musimy zacząć od rozwinięcia go do kostki, tak jak robi to interpreter Cubix:
Jest to quine w stylu Befunge, która działa poprzez wykorzystanie zawijania, aby literały łańcuchowe „zawijały” kod wykonywalny (tylko z jednym
"
znakiem, kod jest jednocześnie wewnątrz i na zewnątrz cytatu, co staje się możliwe, gdy masz programy nieliniowe i nieplanarne). Zauważ, że pasuje to do naszej definicji właściwego quine, ponieważ dwa z podwójnych cudzysłowów nie kodują się same, ale raczej są obliczane później za pomocą arytmetyki.Jednak w przeciwieństwie do Befunge używamy tutaj czterech ciągów zamiast jednego. Oto, w jaki sposób są wypychani na stos;
Program rozpoczyna się u góry lewej krawędzi i idzie w prawo; skręca dwa razy w prawo (
R
), co powoduje, że leci w lewo wzdłuż trzeciej i ostatniej linii otaczającej cały sześcian. Podwójny cudzysłów pasuje do siebie, więc wypychamy całą trzecią linię na stos do tyłu. Następnie wykonanie jest kontynuowane po podwójnym cytacie.u
Komenda robi zawracania w prawo, więc następna rzecz, którą używasz jest z'"
roku na środkowej linii. To popycha a"
na stos. Kontynuując owijanie, uderzamy w<
lewą stronę sześcianu i odbijamy się. Zbliżając się z tego kierunku, widzimy proste"
polecenie,'"
więc nie , więc cała druga linia jest wypychana na stos do tyłu powyżej trzeciej linii i podwójnego cudzysłowu.Zaczynamy od wpychania a
!
na stos ('!
) i zwiększania go ()
); powoduje to podwójny cudzysłów bez konieczności podwójnego cudzysłowu w naszym kodzie źródłowym (co mogłoby zakończyć ciąg znaków). Lustro (\
) odzwierciedla kierunek wykonywania w górę na północ; następnieW
polecenie przesuwa się w lewo. To powoduje, że idziemy w górę siódmej kolumny, która ponieważ jest to sześcian, zawija się w lewo w trzecim rzędzie, a następnie w dół w trzeciej kolumnie. Trafiamy wR
, skręcamy w prawo i idziemy w lewo wzdłuż górnego rzędu; następnie$
przeskakujeR
przez który weszliśmy do programu, więc wykonanie jest zawijane do"
końca na końcu linii, i przechwytujemy pierwszą linię w ciągu znaków w taki sam sposób, jak zrobiliśmy to dla drugiej i trzeciej.^
Komenda wysyła nas na północ, aż do kolumny, która jest jedenastym (umożliwiającej owijania kostki) w kierunku południowym na piątą. Jedyne, co tam napotykamy!
(pomiń, jeśli niezerowe; górna część stosu jest rzeczywiście niezerowa), które pomijająo
polecenie, skutecznie powodując, że piąta kolumna jest całkowicie pusta. Wracamy więc dou
polecenia, które ponownie zawraca, ale tym razem zostajemy w ostatniej kolumnie na południe, która zawija się do czwartej kolumny na północ. Jednak podczas zawracania trafiliśmy w podwójny cudzysłów, więc przechwytujemy całą czwartą kolumnę w ciągu, od dołu do góry. W przeciwieństwie do większości podwójnych cudzysłowów w programie, ten nie zamyka się; jest raczej zamknięty przez prawy"
górny róg, co oznacza, że przechwytujemy ciąg dziewięciu znaków...>.....
.Tak więc układ stosu jest teraz, od góry do dołu: czwarta kolumna; Górny rząd;
"
; środkowy rząd;"
; Dolny rząd. Każdy z nich jest reprezentowany na stosie, przy czym pierwszy znak znajduje się najbliżej góry stosu (Cubix popycha łańcuchy w odwrotnej kolejności, podobnie jak Befunge, ale za każdym razem, gdy IP porusza się w kierunku przeciwnym do naturalnego kierunku odczytu, więc zostało dwukrotnie odwrócone). Można zauważyć, że zawartość stosu jest prawie identyczna z oryginalnym programem (ponieważ czwarta kolumna i północna / górna ściana sześcianu zawierają te same znaki w tej samej kolejności; oczywiście tak zostało zaprojektowane celowo).Następnym krokiem jest wydrukowanie zawartości stosu. Po wszystkich pchnięciach IP idzie w kierunku północnym w czwartej kolumnie, więc uderza
>
tam i wchodzi w ciasną pętlę>>o;?
(tj. „Skręć na wschód, skręć na wschód, wyjdź jako postać, pop, skręć w prawo, jeśli jest dodatnia”). Ponieważ siódma linia jest pełna NOP, funkcja zwinie?
się z powrotem do pierwszej>
, więc skutecznie wypycha całą zawartość stosu (?
jest to brak operacji na pustym stosie). Prawie wydrukowaliśmy cały program! Niestety jeszcze nie zostało to zrobione; na końcu brakuje podwójnego cudzysłowu.Po zakończeniu pętli odbijamy się od linii środkowej, przesuwając się na zachód, przez parę luster. (
\
Wcześniej używaliśmy „drugiej strony” lustra; teraz używamy strony południowo-zachodniej./
Lustro nie było wcześniej używane.) Napotykamy'!
, więc wciskamy wykrzyknik (tj. 33; używamy ASCII a Cubix nie rozróżnia liczb całkowitych i znaków) na stosie. (Dogodnie jest to to samo,!
coo
wcześniej pominięte polecenie). Napotykamy paręR
poleceń i używamy ich do wykonania „ręcznego” zawracania (drugieR
polecenie zostało użyte wcześniej, aby dotrzeć do pierwszego wiersz, więc wydawało się najbardziej naturalne, aby dopasować inne polecenie, aby ominąć lewą stronę.R
polecenie.W
>
polecenie w drugim wierszu, odbijając wykonanie dokładnie tam, gdzie było. Więc znów przeskakujemy w lewo, ale tym razem idziemy na południe, więc następnym poleceniem do wykonania jest)
(inkrementacja wykrzyknika w podwójny cudzysłów), a następnieo
(w celu wyjścia). Na koniec wykonanie jest zawijane wzdłuż ósmej linii do drugiej kolumny, gdzie znajduje się@
wyjście z programu.Przepraszam za zbłąkany apostrof w trzeciej linii. W tej wersji programu nic nie robi; była to część wcześniejszego pomysłu, który miałem, ale który okazał się niekonieczny. Jednak kiedy już dostałem działający quine, po prostu chciałem go przesłać, zamiast zepsuć go dalej, zwłaszcza że usunięcie go nie zmieniłoby liczby bajtów. Jeśli chodzi o dalszą grę w golfa, nie zaskoczyłoby mnie to, gdyby było to możliwe przy 3 × 3 tylko przy użyciu pierwszych pięciu linii, ale nie widzę oczywistego sposobu na zrobienie tego i musiałbym jeszcze ściślejsze upakowanie całego przepływu kontrolnego wraz z innym sposobem przedstawienia górnej powierzchni sześcianu (lub modyfikacją algorytmu, aby mógł nadal używać czwartej kolumny, nawet jeśli miałby teraz dziesięć lub jedenaście znaków) .
źródło
"
jestQ
.Python 2, 30 bajtów
Zabrano stąd
źródło
_
, ale brzmi lepiej, jeśli przypiszesz ją do dowolnej litery, tzn. S:s='s=%r;print s%%s';print s%s
Vim,
17, 14 naciśnięć klawiszyKtoś losowo to ocenił, więc przypomniałem sobie, że istnieje. Kiedy go ponownie przeczytałem, pomyślałem: „Hej, mogę zrobić coś więcej!”, Więc oderwałem dwa bajty. To wciąż nie jest najkrótszy, ale przynajmniej poprawa.
Przez długi czas zastanawiałem się, czy możliwe jest użycie vim quine. Z jednej strony musi być to możliwe, ponieważ vim jest już gotowy. Ale po długim poszukiwaniu vim quine nie byłem w stanie go znaleźć. I nie uważają tego PPCG wyzwanie , ale jest zamknięty i nie dokładnie o dosłowne quines. Zdecydowałem się na taki, ponieważ nie mogłem go znaleźć.
Jestem naprawdę dumny z tej odpowiedzi z dwóch pierwszych powodów :
To pierwszy quine, jaki kiedykolwiek stworzyłem
O ile mi wiadomo, to pierwsza na świecie publikacja vim-quine ! Mogę się mylić w tej sprawie, więc jeśli znasz jedną, daj mi znać.
Po tym długim wprowadzeniu oto:
Wypróbuj online!
Pamiętaj, że po wpisaniu tego
<esc>
klawisza wyświetli się jako^[
. Jest to nadal dokładne, ponieważ^[
reprezentuje0x1B
, co jest ucieczką w ASCII , a sposób, w jaki vim wewnętrznie reprezentuje<esc>
klucz.Zauważ również , że testowanie to może się nie powieść, jeśli załadujesz istniejącą sesję vim. Napisałem wskazówki odpowiedzieć wyjaśniając, że tutaj , jeśli chcesz uzyskać więcej informacji, ale przede wszystkim trzeba uruchomić z vim
lub wpisz
qqq
przed uruchomieniem tego.Wyjaśnienie:
Na marginesie, ta odpowiedź jest prawdopodobnie rekordem świata dla większości q w odpowiedzi PPCG lub coś w tym rodzaju.
źródło
2i2i<esc>
jest tak blisko. Czuję, że musi być coś, co mogę zrobić, aby to zadziałało.<Esc>
jest ukryty w V, więc to działa . Niestety dodaje również nowy wiersz, dlatego jeszcze go nie opublikowałem.q"iq"qbP<Esc>qbP
ma 11. Po umieszczeniu tego na reddit , zbadałem tutaj vimgolfing i postanowiłem założyć konto. Oto odpowiedź, którą tam zamieściłem.utracone ,
120 116 98 96 76 7066 bajtówEdycja: tak, poniżej 100
Edycja: Zapisano kilka bajtów, przełączając na wszystkie
/
s w dolnym wierszuWypróbuj online! + weryfikacja jest deterministyczna dla wszystkich możliwych stanów
Lost to język 2D, w którym pozycja początkowa i kierunek są całkowicie losowe. Oznacza to, że na każdym etapie musi być dużo sprawdzania błędów, aby upewnić się, że masz prawidłowy wskaźnik instrukcji, i nie jest to taki, który właśnie wędrował losowo.
Wyjaśnienie:
Wszystkie
/
s w dolnej linii są tam, aby upewnić się, że wszystkie wskaźniki, które spawnują się w kierunku pionowym lub w dolnej linii, zostaną umieszczone we właściwym kierunku. Stamtąd kończą w kilku różnych miejscach, ale wszystkie trafiają prosto doKtóry usuwa wszystkie niezerowe liczby ze stosu. The
([
Potem czyści żadnych dodatkowych 0s również.W środku klarowania uderza w
%
, co wyłącza „bezpieczeństwo”, co pozwala programowi zakończyć się, gdy trafi@
(bez tego program mógłby zakończyć się natychmiast, jeśli wskaźnik uruchomi się na@
).Stamtąd robi dość prosty quine język 2D, owijając literał ciąg (
"
) wokół pierwszego wiersza, popychając"
znak, kopiując spację (:2+
), a następnie nową linię (52*
). W drugim wierszu tworzy/
znak (95*2+
) i powiela go pęczek (>::1?:[:[[[[
), zanim ostatecznie kończy się na@
i niejawnie drukuje stos. Ma?1
to na celu powstrzymanie procesu tworzenia zbyt wielu zer, jeśli wskaźnik wejdzie wcześnie, oszczędzając na konieczności ich późniejszego usunięcia.Zapisałem tutaj 20 bajtów, czyniąc ostatni wiersz tym samym znakiem, co oznacza, że mogłem przejść od procesu kopiowania do końca
@
.Objaśnienie procesu kopiowania:
[
to postać znana jako „drzwi”. Jeśli wskaźnik uderza w płaską stronę a[
lub a]
, odbija się, w przeciwnym razie przechodzi przez niego. Za każdym razem, gdy wskaźnik wchodzi w interakcje z drzwiami, zmienia się na przeciwny typ. Korzystając z tej wiedzy, możemy skonstruować prosty wzór na to, ile razy instrukcja wykona się w>:[
bloku.Dodaj początkową liczbę instrukcji. Do każdego
[
dodaj 2 razy więcej instrukcji po lewej stronie. Na przykład>::::[:[[[
zaczynamy od 5 jako kwoty początkowej. Pierwsze drzwi mają 4 instrukcje dupe, więc dodajemy 4 * 2 = 8 do 5, aby uzyskać 13. Pozostałe trzy drzwi mają 5 duplikatów po lewej stronie, więc dodajemy 3 * (5 * 2) = 30 do 13, aby uzyskać 43 wykonane instrukcje dupe i mają 44>
s na stosie. Ten sam proces można zastosować do innych instrukcji, takich jak(
wypychanie dużej liczby przedmiotów ze stosu do lunety lub, jak tutaj zastosowano, do usuwania przedmiotów ze stosu.Sztuczka, której użyłem tutaj, aby uniknąć kopiowania zbyt wielu zer, to
1?
. Jeśli znak ma wartość 0,?
nie pomija 1, co oznacza, że duplikuje 1 przez pozostałą część dupe. To znacznie ułatwia późniejsze wyczyszczenie stosu.źródło
Są to dwie najkrótsze rubinowe quiny z SO :
i
Nie pytaj mnie, jak działa ten drugi ...
źródło
<<2
rozpoczyna ciąg w następnym wierszu i*2
powtarza ciągRozszczepienie , 6 bajtów
Wygląda na to, że jest to obecnie najkrótszy „właściwy” quine spośród tych odpowiedzi.
Wyjaśnienie
Przepływ kontrolny zaczyna się
R
od pojedynczego prawego(1,0)
atomu. Uderza w"
tryb przełączania, a następnie owija się wokół linii, drukując'!+OR
przed ponownym naciśnięciem tego samego"
i wychodzeniem z trybu drukowania.To pozostawia
"
się do wydrukowania. Najkrótsza droga to'"O
(gdzie'"
ustawia masę atomu na kod znaku"
iO
drukuje znak i niszczy atom), ale jeśli to"
zrobilibyśmy, to zakłócałoby tryb drukowania. Zamiast tego ustawiamy wartość atomu na'!
(jeden mniej niż"
), następnie zwiększamy za pomocą,+
a następnie drukujemy wynik za pomocąO
.Alternatywy
Oto kilka alternatyw, które są dłuższe, ale może ich techniki zainspirują kogoś do znalezienia krótszej wersji, która je wykorzysta (a może będą bardziej przydatne w niektórych uogólnionych quinach).
8 bajtów przy użyciu
J
umpPonownie kod zaczyna się od
R
.@
Masa swap, energia dać(0,1)
. DlategoJ
sprawia, że atom przeskakujeO
prosto na"
. Następnie, jak poprzednio, wszystkie oprócz tych"
są drukowane w trybie ciągów. Następnie atom uderza,|
aby odwrócić swój kierunek, a następnie przechodzi przez'"O
drukowanie"
. Przestrzeń jest nieco denerwująca, ale wydaje się konieczna, ponieważ w przeciwnym razie'
atom potraktowałby atom|
jak postać zamiast lustra.8 bajtów przy użyciu dwóch atomów
Ma dwa atomy, zaczynając od lewej i od
L
prawejR
. Lewostronny atom otrzymuje swoją wartość, dzięki'"
której jest natychmiast drukowany za pomocąO
(i atom jest niszczony). Dla właściwego atomu ponownie zamieniamy masę i energię, przeskakujemy nad,O
aby wydrukować resztę kodu w trybie drukowania. Następnie jego wartość jest ustawiana przez,'L
ale to nie ma znaczenia, ponieważ atom jest następnie odrzucany za pomocą;
.źródło
'!+
koduje"
.|R@JO"'
zadziałałoby, czy nadal potrzebowałbyś tego miejsca po'
?'
pierwszy.JavaScript w przeglądarce (41 znaków)
Działa w 5 najlepszych przeglądarkach internetowych (IE> = 8, Mozilla Firefox, Google Chrome, Safari, Opera). Wpisz go do konsoli programisty w jednym z poniższych:
To nie jest „oszustwo” - w przeciwieństwie do jednobajtowego quina Chrisa Jester-Younga, ponieważ można go łatwo zmodyfikować, aby używał tej
alert()
funkcji (kosztuje 14 znaków):Lub przekształcony w bookmarklet (kosztuje 22 znaki):
źródło
C,
6460 bajtówJak dotąd jest to najkrótsza znana quina C. Tam jest rozszerzony Bounty jeśli okaże się krótsza.
Działa to w GCC , Clang i TCC w środowisku POSIX . W przypadku wszystkich z nich wywołuje nadmierną liczbę niezdefiniowanych zachowań.
Dla zabawy, oto repozytorium zawierające wszystkie znane mi litery C. Zachęcamy do rozwidlenia / PR, jeśli znajdziesz lub napiszesz inny, który doda coś nowego i kreatywnego w stosunku do istniejących.
Pamiętaj, że działa tylko w środowisku ASCII . To działa dla EBCDIC , ale nadal wymaga POSIX . Powodzenia w znalezieniu środowiska POSIX / EBCDIC: P
Jak to działa:
main(s)
nadużywamain
argumentów, deklarując zmienną praktycznie bez typus
. (Pamiętaj, żes
tak naprawdę nie jest to bez typu, ale ponieważ wymienione kompilatory automatycznie rzutują go w razie potrzeby, równie dobrze może być *).printf(s="..."
zestawys
podany ciąg i przekazuje pierwszy argument doprintf
.s
jest ustawiony namain(s){printf(s=%c%s%1$c,34,s);}
.%c
Jest ustawione na ASCII34
,"
. To umożliwia quine. Terazs
wygląda następująco:main(s){printf(s="%s%1$c,34,s);}
.%s
Jest ustawiony nas
sobie, co jest możliwe dzięki # 2. Terazs
wygląda następująco:main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}
.%1$c
Jest ustawione na ASCII 34"
,printf
„s ** pierwszy argument. Terazs
wygląda to tak:main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
... tak się składa, że jest to oryginalny kod źródłowy.
* Przykład dzięki @Pavel
** pierwszy argument po specyfikacją formatu - w tym przypadku
s
. Odwołanie do specyfikatora formatu jest niemożliwe.Myślę, że to niemożliwe, żeby to samo się skróciło. Gdyby
printf
specyfikator formatu był dostępny przez$
, działałoby to dla 52 bajtów:źródło
s
jest typuint
, a nie „zmienną bez typu”.s=3
oczywiście nie zadziałałoby, ponieważ musisz dwukrotnie przekazać ciągprintf
.Java, 528 bajtów:
Rozwiązanie Java z oryginalnym podejściem:
w czytelnej formie:
źródło
if(++i==92)
,a*
ponieważ tablica nie wychodzi z Javy, to jest C. Niektóre inne elementy golfa:import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("abc",36);int i=0;for(int c:b.toByteArray())System.out.printf("%s%c",++i==92?b.toString(36):"",c);}}
gdzieabc
byłaby nowo obliczona magiczna liczba String. W Javie 8+ jest to również możliwe, aby zmienićclass a{public static void main
sięinterface a{static void main
, aw Java 10+ jest to również możliwe, aby zmienićimport java.math.*;
iBigInteger b=new BigInteger(
dovar b=new java.math.BigInteger(
.Kurczak , 7
Nie, to nie jest bezpośrednio powtarzane :)
źródło
chicken
!Siatkówka ,
201497 bajtówZanim zaczniemy, chciałbym wspomnieć o trywialnym rozwiązaniu pliku, który zawiera jeden plik
0
. W takim przypadku Retina spróbuje policzyć0
s na pustym wejściu, czego wynikiem jest również0
. Nie uważałbym jednak tego za dobry quine.Oto właściwy:
Wypróbuj online!
Alternatywnie, moglibyśmy użyć
;
zamiast>
.Wyjaśnienie
Program składa się z jednego zamiennika, który drukujemy dwukrotnie.
W pierwszym wierszu
`
separuje konfigurację od wyrażenia regularnego, więc wyrażenie jest puste. Dlatego pusty ciąg (tj. Nieistniejące wejście) jest zastępowany drugim wierszem, dosłownie.Aby wydrukować wynik dwukrotnie, zawijamy go w dwa etapy wyjściowe. Wewnętrzny
\
drukuje wynik z końcowym podawaniem linii, a zewnętrzny,>
drukuje go bez niego.Jeśli jesteś trochę zaznajomiony z Retiną, możesz zastanawiać się, co się stało z dorozumianymi wynikami Retiny. Domniemane wyjście Retiny polega na zawinięciu ostatniego etapu programu w etap wyjściowy. Jednak Retina tego nie robi, jeśli ostatni etap jest już etapem wyjściowym. Powodem tego jest to, że w normalnym programie bardziej użyteczna jest możliwość zastąpienia domyślnego stopnia wyjściowego specjalnym stopniem podobnym
\
lub;
pojedynczym bajtem (zamiast konieczności pozbycia się domyślnego stopnia z.
flagą). Niestety takie zachowanie kosztuje nas dwa bajty na quine.źródło
JavaScript (36 znaków)
To jest AFAICT, najkrótsza jak dotąd napisana javascript.
źródło
a
, możesz uzyskać dostęp do jej zawartości przez wywołaniea.toString
.a
dokładnie w taki sam sposób, jak napisano powyżej. Jednak dane wyjściowe tego kodu mogą być quine w każdej implementacji JavaScript.!function a(){alert("!"+a+"()")}()
.(a=()=>alert(
({a})))()
GolfScript, 8 bajtów
Zawsze myślałem, że najkrótsza (prawdziwa) Quine GolfScript ma 9 bajtów:
Tam, gdzie konieczne jest końcowe podawanie linii, ponieważ GolfScript domyślnie drukuje końcowe podawanie linii.
Ale właśnie znalazłem 8-bajtowy quine, który działa dokładnie wokół tego ograniczenia wysuwu linii:
Wypróbuj online!
Więc haczyk polega na tym, że GolfScript nie drukuje końcowego przesuwu linii, ale drukuje zawartość
n
na końcu programu. Po prostun
zawiera on źródło na początek. Pomysł polega więc na zastąpieniu go łańcuchem":n`"
, a następnie jego usztywnieniu, tak aby kopia na stosie była drukowana z cytatami i kopią przechowywaną nan
odcinkach bez.Jak zauważył Thomas Kwa, 7-bajtowy quine CJam można również dostosować do 8-bajtowego rozwiązania:
Znowu potrzebujemy końcowego przewodu.
źródło
Labirynt ,
12411053 bajtówDzięki Sp3000 za grę w golfa z 9 bajtów, co pozwoliło mi grać w golfa z kolejnymi 7.
Wypróbuj online!
Wyjaśnienie
Labirynt 101:
n*10 + <digit>
. Pozwala to na łatwe budowanie dużych liczb. Aby rozpocząć nowy numer, użyj_
, który wypycha zero."
nie ma operacji.Najpierw wyjaśnię nieco prostszą wersję, która jest dłuższa, ale trochę mniej magiczna:
Wypróbuj online!
Główną ideą jest zakodowanie głównej części źródła w jednym numerze, z wykorzystaniem dużej bazy. Numer ten można następnie łatwo wydrukować, zanim zostanie zdekodowany w celu wydrukowania pozostałej części kodu źródłowego. Dekodowanie jest po prostu powtórzeniem aplikacji
divmod base
, w której wypisujemod
i kontynuuje pracę z dodiv
do zera.Unikając tego
{}
, najwyższy potrzebny nam kod znaków to_
(95), tak że podstawa 96 jest wystarczająca (utrzymując bazę na niskim poziomie, liczba na początku jest krótsza). Więc chcemy zakodować to:Przekształcając te znaki w ich punkty kodowe i traktując wynik jako liczbę podstawową 96 (z najmniej znaczącą cyfrą odpowiadającą
!
i najbardziej znaczącą do.
, ponieważ jest to kolejność, w jakiej rozłożymy liczbę), otrzymujemyTeraz kod zaczyna się od całkiem fajnej sztuczki (jeśli mogę tak powiedzieć), która pozwala nam wydrukować kodowanie z powrotem i zachować kolejną kopię do dekodowania z niewielkim narzutem: wstawiamy liczbę do kodu w odwrotnej kolejności. Obliczyłem wynik za pomocą tego skryptu CJam Przejdźmy więc do właściwego kodu. Oto początek:
Adres IP zaczyna się w lewym górnym rogu i idzie na wschód. Przesuwając te cyfry, po prostu gromadzi tę liczbę na wierzchu stosu. Sama liczba jest całkowicie bez znaczenia, ponieważ jest odwrotnością tego, czego chcemy. Gdy adres IP trafi do
!
, wyskakuje ten numer ze stosu i drukuje go. To wszystko, aby odtworzyć kodowanie na wyjściu.Ale teraz IP dotarło w ślepy zaułek. Oznacza to, że odwraca się i teraz wraca na zachód (bez
!
ponownego wykonywania ). Tym razem, dogodnie, adres IP odczytuje liczbę od tyłu do przodu, tak więc teraz robi to liczba na górze stosu kodować resztę źródła.Kiedy IP teraz znów uderza w lewy górny róg, nie jest to ślepy zaułek, ponieważ IP może skręcić w lewo, więc robi to i teraz przesuwa się na południe.
"
Jest no-op, że musimy tu oddzielić od liczby pętli głównej kodeksu. A propos:Dopóki górna część stosu nie jest jeszcze równa zero, adres IP będzie przebiegał przez ten raczej gęsty kod w następującej pętli:
Lub ułożone liniowo:
Powodem, dla którego zabiera te zakręty, jest semantyka sterowania przepływem Labiryntu. Gdy w bieżącej komórce znajduje się co najmniej trzech sąsiadów, IP skręci w lewo na ujemną wartość stosu, przejdź do zera i skręci w prawo na dodatnią wartość stosu. Jeśli wybrany kierunek nie jest możliwy ze względu na ścianę, IP przyjmie zamiast tego kierunek przeciwny (dlatego w kodzie są dwa zakręty w lewo, chociaż góra stosu nigdy nie jest ujemna).
Sam kod pętli jest właściwie bardzo prosty (kompresowanie go tak ściśle nie było i jest to, gdzie główny wkład Sp3000 jest):
Po osiągnięciu
N
zera zmienia się przepływ kontrolny. Teraz IP chciałby iść prosto za/
(tj. Na zachód), ale tam jest ściana. Zamiast tego, jeśli odwróci się (na wschód), wykonuje6
ponownie. To sprawia, że górna część stosu jest dodatnia, więc IP skręca w prawo (południe) i wykonuje9
. Szczyt stosu jest teraz69
, ale zależy nam tylko na tym, aby był pozytywny. IP wykonuje kolejny zakręt w prawo (na zachód) i przesuwa się na@
który kończy kod.W sumie całkiem proste.
Okej, teraz jak golimy ten dodatkowy bajt. Oczywiście ten brak operacji wydaje się marnotrawstwem, ale potrzebujemy tego dodatkowego wiersza: jeśli pętla przylegałaby do liczby, adres IP już by się tam przeniósł zamiast przemieścić cały numer. Czy możemy zrobić coś przydatnego z tym brakiem operacji?
Zasadniczo możemy tego użyć, aby dodać ostatnią cyfrę do kodowania. Kodowanie tak naprawdę nie musi być w pierwszej linii ... po
!
prostu zapewnia, że cokolwiek jest tam , również zostanie wydrukowane.Jest jednak pewien haczyk, nie możemy tego po prostu zrobić:
Problem polega na tym, że teraz zmieniliśmy na
"
a3
, co również zmienia faktyczną liczbę, którą chcemy mieć. I na pewno ta liczba się nie kończy3
. Ponieważ liczba jest całkowicie określana przez kod zaczynający się od!
, nie możemy wiele z tym zrobić.Ale może możemy wybrać inną cyfrę? Tak naprawdę nie dbamy o to, czy jest
3
w tym miejscu, o ile skończymy z liczbą, która poprawnie koduje źródło. Niestety, żadna z 10 cyfr nie daje kodowania, którego najmniej znacząca cyfra odpowiada wybranemu. Na szczęście w pozostałej części kodu jest trochę swobody, dzięki czemu możemy wypróbować jeszcze kilka kodowań bez zwiększania liczby bajtów. Znalazłem trzy opcje:@
na/
. W takim przypadku możemy użyć dowolnej cyfry1357
i uzyskać pasujące kodowanie. Oznaczałoby to jednak, że program kończy działanie z błędem, który jest dozwolony, ale nie wydaje się bardzo czysty._
). 26 wyborów daje wiele możliwości. Np. DlaA
dowolnej cyfry nieparzystej działa. Jest to nieco ładniejsze, ale nadal nie wydaje się aż tak eleganckie, ponieważ nigdy nie użyłbyś tam litery w prawdziwym kodzie.1
, kodowanie również się kończy1
. Jest to jedyne rozwiązanie wśród baz 96, 97, 98, 99, więc jest to naprawdę bardzo szczęśliwe. W ten sposób otrzymujemy kod u góry tej odpowiedzi.źródło
Utracone ,
293262249 bajtówWypróbuj online!
Wyjaśnienie
Cały ten projekt był w górę i w dół. Ciągle myślałem, że to niemożliwe, a potem wpadłem na szalony pomysł, który może po prostu zadziałać.
Dlaczego Lost Quine jest tak trudny?
Jak zapewne wiesz, Lost to język programowania 2D, w którym położenie początkowe i kierunek są całkowicie losowe. To sprawia, że pisanie każdego utraconego programu jest tak trudne, jak pisanie kodu zabezpieczonego przed promieniowaniem. Musisz wziąć pod uwagę każdą możliwą lokalizację i kierunek.
Biorąc to pod uwagę, istnieją pewne standardowe sposoby robienia rzeczy. Na przykład tutaj jest standardowy sposób drukowania łańcucha.
Na dole znajduje się strumień kolekcji, który chwyta większość ips i ciągnie je do miejsca początkowego. Gdy dotrą do miejsca początkowego (lewy górny róg), dezynfekujemy je za pomocą pętli, usuwając wszystkie wartości ze stosu, a następnie obracamy bezpieczeństwo popychania sznurka i wychodzenia. (bezpieczeństwo to koncepcja unikalna dla Lost, że każdy program musi trafić
%
przed wyjściem, co zapobiega możliwości zakończenia programu przy starcie). Teraz moim pomysłem byłoby rozszerzenie tej formy na pełnoprawny quine.Pierwszą rzeczą, którą trzeba było zrobić, było trochę przerobić pętlę, istniejąca pętla była specyficzna dla formatu String.
Musimy dodać drugi strumień, aby uniknąć możliwości
!
przeskakiwania nad strumieniem i tworzenia pętli.Teraz chcemy to połączyć ze standardowym formatem Quine. Ponieważ Lost opiera się w dużej mierze na Kleinie, w
zasadzie ukradłempożyczyłem Klien Quine dla Martina Endera .To dość wygodnie drukuje pierwszą linię quine. Teraz wszystko, co musimy zrobić, to na stałe zakodować strumienie. Łatwiej powiedzieć, niż zrobić. Wypróbowałem około czterech różnych metod, aby to zrobić. Opiszę tylko ten, który zadziałał.
Chodzi o to, aby użyć drzwi, aby uzyskać pożądaną liczbę strzał. Drzwi to specjalny rodzaj lustra, które zmienia się za każdym razem, gdy zostanie uderzone.
[
odzwierciedla IPS przychodzące z lewej i]
prawej strony. Gdy trafi je ip z jednej z tych stron, orientacja przełącznika. Możemy wykonać linię tych drzwi i statyczny odbłyśnik, aby wielokrotnie wykonywać operację.Wykona
:
trzy razy. W ten sposób, jeśli przepchniemy a<
do stosu przed ręką, możemy zrobić ich dużo przy mniejszej liczbie bajtów. Wykonujemy 2 z nich, po jednym dla każdej linii, a między nimi ustanawiamy nową linię, jednak druga wystarczy tylko, dopóki nie obejmie tej!
, do której ją dodaliśmy, wszystko inne może pozostać puste, oszczędzając nam kilka bajtów. Ok, teraz musimy dodać pionowe strzałki do naszych strumieni. W tym miejscu pojawia się optymalizacja klucza. Zamiast przekierowywać wszystkie IP bezpośrednio do „startu” programu, zamiast tego przekierowujemy je w skrajną lewą stronę, ponieważ już wiemy, że IP zaczynające się w skrajnej lewej musidziała (a przynajmniej będzie działać w ostatecznej wersji) możemy również po prostu przekierować inne IPS. To nie tylko sprawia, że jest tańszy w bajtach, ale myślę, że ta optymalizacja umożliwia quine.Jednak wciąż istnieją pewne problemy, z których najważniejszym jest Ips, który został uruchomiony po
>
wypchnięciu go, ale zanim zaczniemy robić jego kopie. Taki IPS wejdzie do kopiarki i utworzy kilka kopii 0. Jest to złe, ponieważ nasz mechanizm czyszczenia stosu używa zer do określania dolnej części stosu, pozostawiając całą wiązkę zer na dole. Musimy dodać silniejszą metodę sanity stosu. Ponieważ nie ma rzeczywistego sposobu stwierdzenia, czy stos jest pusty, będziemy musieli po prostu spróbować zniszczyć jak najwięcej przedmiotów na stosie. Tutaj ponownie zastosujemy metodę drzwi opisaną wcześniej. Dodamy((((((((((([[[[[[[[[[[[[[
do końca pierwszej linii tuż po sanitizor aby pozbyć się zer.Teraz jest jeszcze jeden problem, ponieważ przekierowaliśmy nasze strumienie na lewy górny ips, zaczynając od
%
i przejście w dół już wyłączyło bezpieczeństwo i zakończy się przedwcześnie. Musimy więc wyłączyć bezpieczeństwo. Robimy to poprzez dodanie a#
do strumienia, w ten sposób ips przepływający przez strumień zostanie wyłączony, ale ips, które już zostały zdezynfekowane, nie.#
Musi być zakodowana w pierwszej linii, jak również.To wszystko, mam nadzieję, że rozumiesz, jak to teraz działa.
źródło
Tak ,
1165879606561540522498 + 7 = 505 bajtówWymaga
-cheat
flagi, aby umożliwić definicję aliasów.Wypróbuj online!
Wyjaśnienie
Są to dwie części (jak w większości quines). Dane:
I dekoder:
Dane są jedynie kodowaniem binarnym dekodera (a raczej jego odwrotnością). Każdy
0
zaczyna nową postać, a1
s i2
s są0
- i1
bits, odpowiednio.Zauważ, że
0
jest to standardowe polecenie Yup, które przesuwa zero, podczas gdy1
i2
nie jest w tym momencie zdefiniowane. Przypisujemy jednak całą część danych do polecenia,%
aby1
i2
mogły pozostać niezdefiniowane, dopóki nie%
zostaną faktycznie użyte.Następnie definiujemy kilka kolejnych poleceń:
<
zmniejsza górną część stosu,>
zwiększa ją.1
(nieco nieumyślnie) podwaja górę stosu.2
podwaja go, a następnie zwiększa. Dzięki tym definicjom coś takiego0221111
pozostawi na stosie 48 (110000 binarnie).Pozostałe 32 bajty faktycznie dekodują w dwóch częściach. Najpierw musimy zrekonstruować ciąg danych.
I na koniec ponownie wypychamy dane i wypisujemy każdą wartość jako znak:
Do wykorzystania w przyszłości, oto skrypt CJam do kodowania danych.
źródło
Fueue , 423 bajty
Fueue to esolang oparty na kolejce, w którym działającym programem jest kolejka.
Wypróbuj online!
Jak to działa
To wyjaśnienie
mogłowymknąć się spod kontroli. Z drugiej strony nie wiem, jak wyjaśnić to znacznie krócej, w sposób, w jaki mam nadzieję, że ludzie będą w stanie to zrobić.Ściągawka Fueue
Zobacz artykuł wiki esolang, aby uzyskać szczegółowe informacje, w tym kilka funkcji nieużywanych w tym programie.
Program początkowy to stan początkowy kolejki, który może zawierać następujące elementy:
+*/-%
: arytmetyka liczb całkowitych (-
jest jednostkowa,%
logiczna negacja). Obojętne, jeśli nie podano argumentów liczbowych.()<
: wstaw element w nawiasach, usuń nawiasy z bloku, dodaj ostatni element do bloku. Dwa ostatnie są obojętne, chyba że następuje po nich blok.~:
: zamiana, duplikat.$
: kopia (pobiera liczbę + element). Obojętny przed nieliczbowymH
: zatrzymanie programu.Zauważ, że podczas
[]
zagnieżdżania,()
nie - te ostatnie są po prostu osobnymi funkcjami.Składnia śledzenia wykonania
Białe znaki są opcjonalne w Fueue, z wyjątkiem cyfr. W poniższych śladach wykonania zostanie on użyty do zasugerowania struktury programu, w szczególności:
Nawiasy klamrowe
{}
(nieużywane w Fueue) są używane w śladach do reprezentowania wyniku liczb całkowitych wyrażeń matematycznych. Obejmuje to liczby ujemne, ponieważ Fueue ma tylko nieujemne literały --
jest funkcją negacji.Różne nazwy meta-zmiennych i
...
służą do oznaczania wartości i skrótów.Opóźnianie taktyki
Intuicyjnie wykonywanie odbywa się cyklicznie wokół kolejki, częściowo modyfikując to, przez co przechodzi. Wyniki funkcji nie mogą być ponownie wykorzystane do następnego cyklu. Różne części programu ewoluują równolegle, o ile nie wchodzą w interakcje.
W rezultacie znaczna część kodu jest poświęcona synchronizacji, w szczególności opóźnieniu wykonania części programu do właściwego czasu. Istnieje wiele opcji gry w golfa, która ma tendencję do przekształcania tych części w nieczytelne obiekty BLOB, które można zrozumieć, śledząc ich wykonanie cykl po cyklu.
Te taktyki nie zawsze będą indywidualnie wymienione poniżej:
)[A]
opóźnieniaA
dla cyklu. (Prawdopodobnie najłatwiejsza i najbardziej czytelna metoda).~ef
zamienia elementye
if
który opóźnia również ich wykonanie. (Prawdopodobnie najmniej czytelny, ale często najkrótszy w przypadku drobnych opóźnień).$1e
opóźnia pojedynczy elemente
.-
i%
są przydatne do opóźniania numerów (te ostatnie dla0
i1
.):
lub$
można je wykorzystać do utworzenia ich z jednego.(n
owija sięn
w nawiasy, które można później wygodnie usunąć. Jest to szczególnie istotne w przypadku obliczeń numerycznych, ponieważ liczby są zbyt niestabilne, aby można je nawet skopiować bez uprzedniego umieszczenia ich w bloku.Ogólna struktura
Pozostałe objaśnienia są podzielone na siedem części, z których każda dotyczy części działającego programu. Większe cykle, po których większość się powtarza, będą nazywane „iteracjami”, aby odróżnić je od „cykli” pojedynczych przejść przez całą kolejkę.
Oto jak dzieli się między nimi program początkowy:
Duża cyfra na końcu programu koduje resztę w odwrotnej kolejności, dwie cyfry na znak, z 30 odejmowanymi od każdej wartości ASCII (np.
10
Koduje a(
.)Na wyższym poziomie możesz myśleć o danych w tym programie (zaczynając od bignum) jako przepływających od prawej do lewej, ale kontrolujących przepływających od lewej do prawej. Jednak na niższym poziomie Fueue cały czas zamazuje rozróżnienie między kodem a danymi.
0
jako liczba całkowita48
), najpierw dzieląc najmniej znaczące cyfry. Wytwarza jedną cyfrę co 15 cykli.[x[y]]
, a także drukując zakodowany znak każdej pary.[x[y]]
bloków w taki sposób, że gdy zawiera wszystkie cyfry, można go uruchomić, aby wydrukować wszystkie z nich, a następnie zatrzymać cały program.Sekcja A
Sekcja A zajmuje się planowaniem końca programu. Zmniejszenie do pojedynczej funkcji wymiany zajmuje 4258 cykli
~
, a następnie dostosowuje odcinek B, który zatrzymuje jego główną pętlę i zamiast tego uruchamia odcinek D.$
Funkcja tworzy 4255 kopie następujących%
natomiast(
owija~
w nawiasach.%
służy do przełączania następującej liczby między0
i1
.%
s zostaną zużyte,$1
tworzona jest 1 kopia[~]
(efektywnie NOP), aw następnym cyklu)
usuwa nawiasy.Sekcja B
Sekcja B zajmuje się regeneracją, a także nową iteracją sekcji C co 30 cykli.
:
duplikuje następujący duży blok (jedna kopia w skrócie[BkB]
), a następnie)
usuwa nawiasy kwadratowe z pierwszej kopii.$$24%%0
ustawia odliczanie podobne do tego w sekcji A.:<
zamienia się<<
i~
zamienia dwa bloki, umieszczając kod nowej sekcji C. na końcu.<
funkcje pakują dwa ostatnie bloki do pierwszego - jest to zbędne w normalnych iteracjach, ale pozwoli na~
wykonanie zadania z sekcji A na końcu.)
usuwa zewnętrzne nawiasy. Następnie~:)
zamienia się w):
i~)
zamienia a)
na początek kodu sekcji C.)
właśnie usuwa nawiasy klamrowe, aby rozpocząć nową iterację sekcji C.W końcowej iteracji
~
sekcja A pojawia się w punkcie (1) powyżej:W
~
zamienia)
na bloku i do sekcji C, zapobiegając sekcja B przed uruchomić ponownie.Sekcja C
Sekcja C obsługuje scalanie nowych par cyfr w bloku sekcji D, a także tworzenie nowych iteracji sekcji E.
Poniżej pokazano typową iterację
x
iy
reprezentację kodów ASCII cyfr. W pierwszej iteracji przychodzące elementy „D” i „E” są początkowe[H]
i-
zamiast tego, ponieważ żadna poprzednia sekcja E nie uruchomiła się, aby utworzyć pary cyfr.~
w jednym rzędzie, rząd zmniejsza się do około 2/3 każdego cyklu (ponieważ jeden~
zamienia dwa kolejne), ale czasami z resztą~
s, którasiejąc spustoszenie,ostrożnie manipuluje następującymi.$11~
produkuje taki rząd. Następny~
zamienia a<
w następnym bloku. Inny<
na końcu dołącza nowy blok par cyfr (cyfry xiy jako kody ASCII) do bloku sekcji D.~
wiersz ma~~
resztę, która zamienia a~
na następną)
. Druga<
dołącza sekcję D do[)))~]
bloku.~
sama zamiana zamienia następujący blok z nowym kodem sekcji E w bloku sekcji D. Następnie nowa resztka~
zamienia krzyż)
, a na koniec ostatni~~
z~
rzędu zamienia jeden z nich na odcinek E, gdy tylko)
usunął nawiasy.W końcowej iteracji sekcja A
~
zamieniła)
przekrój przez sekcję B i na sekcję C. Jednak sekcja C jest tak krótkotrwała, że już zniknęła, a)
kończy się na początku sekcji D.Sekcja D
Sekcja D zajmuje się wydrukowaniem ostatniej dużej cyfry i zatrzymaniem programu. Przez większość przebiegu programu jest to obojętny blok, w którym sekcje B – G współpracują przy budowie.
(
funkcja nawijania otaczaH
nawiasy.-
Poniżej, będzie stosowany jako obojętne element pierwszej iteracji zamiast cyfr pary.[49[49]]
, odpowiadająca końcowej11
cyfrze.[49[48]]
(odpowiadający10
na początku liczebnika) w rzeczywistości nie jest włączona do bloku, ale to nie ma znaczenia, jak)[A[B]]
i)[A][B]
odpowiadają zarówno zmienia sięA[B]
.Po ostatniej iteracji następuje
)
zamiana w prawo z sekcji B i blok sekcji D zostaje odblokowany. Na)))~
początku każdego podbloku upewnia się, że wszystkie części są wykonywane we właściwej kolejności. Wreszcie najbardziej wewnętrzny blok zawieraH
zatrzymanie programu.Sekcja E
Sekcja E obsługuje łączenie par cyfr ASCII wytworzonych przez sekcję G i obie drukują odpowiedni zakodowany znak i wysyła blok z połączoną parą w lewo do sekcji C i D.
Ponownie poniżej pokazano typową iterację
x
iy
reprezentację kodów ASCII cyfr.10*x+y-498
, wartość ASCII zakodowanego znaku.498 = 10*48+48-30
,48
s cofnie kodowanie ASCIIx
iy
podczas gdy30
przesuwa kodowanie z00–99
na30–129
, co obejmuje wszystkie drukowalne ASCII.Sekcja F.
Sekcja F składa się z obojętnych bloków zawierających kody cyfr ASCII. W przypadku większości uruchomionych programów będą tu maksymalnie dwa, ponieważ sekcja E zużywa je z tą samą prędkością, z jaką wytwarza je G. Jednak w końcowej fazie drukowania
0
zostaną tutaj zebrane zbędne cyfry.Sekcja G
Sekcja G obsługuje dzielenie dużej liczby na końcu programu, najpierw najmniej znaczących cyfr, i wysyłanie bloków z kodami ASCII w lewo do innych sekcji.
Ponieważ nie ma kontroli zatrzymania, w rzeczywistości będzie kontynuował generowanie
0
cyfr, gdy liczba zmniejszy się do 0, dopóki sekcja D nie zatrzyma całego programu zH
funkcją.[BkG]
skraca kopię dużego bloku kodu początkowego, który służy do samoreplikacji w celu rozpoczęcia nowych iteracji.Inicjalizacja w pierwszych cyklach:
Typowa iteracja
N
oznacza liczbę do podzielenia:+:5
zamiast--10
opóźnienia10
dwóch cykli. Niestety10
pomógł tylko jeden z programów.[N]
I[BkG]
bloki są powielane, a następnie jeden egzemplarzN
jest podzielona10
.[{N/10}]
jest duplikowane, wówczas do obliczenia kodu ASCII ostatniej cyfryN
as stosuje się więcej funkcji arytmetycznych48+((-10)*(N/10)+N)
. Blok z tym kodem ASCII pozostawia się w sekcji F.[{N/10}]
zostaje zamieniona między[BkG]
blokami, aby ustawić początek nowej iteracji.Quine bonusowa (540 bajtów)
Wypróbuj online!
Ponieważ nie byłem pewien, która metoda będzie najkrótsza, najpierw spróbowałem zakodować znaki jako liczby dwucyfrowe oddzielone
(
s. Kod podstawowy jest nieco krótszy, ale rekompensuje to 50% większa reprezentacja danych. Nie tak golfowy jak ten drugi, ponieważ zatrzymałem się, kiedy zdałem sobie sprawę, że to nie przebije. Ma jedną zaletę: nie wymaga implementacji z obsługą bignum.Jego ogólna struktura jest nieco podobna do głównej. Brak sekcji G, ponieważ reprezentacja danych wypełnia bezpośrednio sekcję F. Jednak sekcja E musi wykonać podobne obliczenia divmod, aby zrekonstruować cyfry liczb dwucyfrowych.
źródło
)$n[)](
jest bajtem krótszym dla licznika opóźnienia.Galaretka, 3 bajty
Wypróbuj online!
Weryfikacja
Jak to działa
źródło
LANG=en_US
osiąga właśnie to. tio.run/nexus/bash#@@/…