Golf te a quine per il bene!


204

Usando la tua lingua preferita, golf a quine .

Un quine è un programma per computer non vuoto che non accetta input e produce una copia del proprio codice sorgente come unico output.

Nessun imbroglio: ciò significa che non puoi semplicemente leggere il file sorgente e stamparlo. Inoltre, in molte lingue, anche un file vuoto è un quine: neanche questo è considerato un quine legittimo.

Nessuna query di errore: esiste già una sfida separata per le query di errore.

Punti per:

  • Codice più piccolo (in byte)
  • La soluzione più offuscata / oscura
  • Uso di linguaggi esoterici / oscuri
  • Uso con successo di lingue in cui è difficile giocare a golf

Il seguente frammento di stack può essere utilizzato per ottenere una rapida visualizzazione del punteggio corrente in ciascuna lingua e, quindi, per sapere quali lingue hanno risposte esistenti e che tipo di target devi battere:


4
Non vuoi dire "Golf sei un quine per un bene superiore!"?
Mateen Ulhaq,

50
@muntoo è un gioco teatrale su "Learn you a Haskell for Great Good".
Rafe Kettler,

Risposte:


106

Esagonia , lunghezza laterale 17 16, 816 705 byte

180963109168843880558244491673953327577233938129339173058720504081484022549811402058271303887670710274969455065557883702369807148960608553223879503892017157337685576056512546932243594316638247597075423507937943819812664454190530214807032600083287129465751195839469777849740055584043374711363571711078781297231590606019313065042667406784753422844".".>.@.#.#.#.#.#.#.#.>.(...........................<.".......".".>./.4.Q.;.+.<.#.>...........................<.".....".".>.#.#.>.N.2.'.\.>.............=.=......._.<.".....".".>.>.;.'.=.:.\.>.......................<."...".".>.\.'.%.'.<.#.>..............._.....<."...".".>.#.#.>.<.#.>...............=.=.<.".".".>.#.\.'.R./.>.................<.".!.........../.>.

Provalo online!

Questo è ciò che sembra spiegato:

                1 8 0 9 6 3 1 0 9 1 6 8 8 4 3 8
               8 0 5 5 8 2 4 4 4 9 1 6 7 3 9 5 3
              3 2 7 5 7 7 2 3 3 9 3 8 1 2 9 3 3 9
             1 7 3 0 5 8 7 2 0 5 0 4 0 8 1 4 8 4 0
            2 2 5 4 9 8 1 1 4 0 2 0 5 8 2 7 1 3 0 3
           8 8 7 6 7 0 7 1 0 2 7 4 9 6 9 4 5 5 0 6 5
          5 5 7 8 8 3 7 0 2 3 6 9 8 0 7 1 4 8 9 6 0 6
         0 8 5 5 3 2 2 3 8 7 9 5 0 3 8 9 2 0 1 7 1 5 7
        3 3 7 6 8 5 5 7 6 0 5 6 5 1 2 5 4 6 9 3 2 2 4 3
       5 9 4 3 1 6 6 3 8 2 4 7 5 9 7 0 7 5 4 2 3 5 0 7 9
      3 7 9 4 3 8 1 9 8 1 2 6 6 4 4 5 4 1 9 0 5 3 0 2 1 4
     8 0 7 0 3 2 6 0 0 0 8 3 2 8 7 1 2 9 4 6 5 7 5 1 1 9 5
    8 3 9 4 6 9 7 7 7 8 4 9 7 4 0 0 5 5 5 8 4 0 4 3 3 7 4 7
   1 1 3 6 3 5 7 1 7 1 1 0 7 8 7 8 1 2 9 7 2 3 1 5 9 0 6 0 6
  0 1 9 3 1 3 0 6 5 0 4 2 6 6 7 4 0 6 7 8 4 7 5 3 4 2 2 8 4 4
 " . " . > . @ . # . # . # . # . # . # . # . > . ( . . . . . .
  . . . . . . . . . . . . . . . . . . . . . < . " . . . . . .
   . " . " . > . / . 4 . Q . ; . + . < . # . > . . . . . . .
    . . . . . . . . . . . . . . . . . . . . < . " . . . . .
     " . " . > . # . # . > . N . 2 . ' . \ . > . . . . . .
      . . . . . . . = . = . . . . . . . _ . < . " . . . .
       . " . " . > . > . ; . ' . = . : . \ . > . . . . .
        . . . . . . . . . . . . . . . . . . < . " . . .
         " . " . > . \ . ' . % . ' . < . # . > . . . .
          . . . . . . . . . . . _ . . . . . < . " . .
           . " . " . > . # . # . > . < . # . > . . .
            . . . . . . . . . . . . = . = . < . " .
             " . " . > . # . \ . ' . R . / . > . .
              . . . . . . . . . . . . . . . < . "
               . ! . . . . . . . . . . . / . > .
                . . . . . . . . . . . . . . . .

Ah bene, questo era abbastanza le montagne russe emotiva ... ho smesso di contare il numero di volte in cui sono passato tra le "haha, questa è follia" e "aspetta, se faccio questo che dovrebbe in realtà essere abbastanza fattibile". I vincoli imposti al codice dalle regole di layout di Hexagony erano ... severi.

Potrebbe essere possibile ridurre la lunghezza laterale di 1 o 2 senza cambiare l'approccio generale, ma sarà difficile (solo le celle con #sono attualmente inutilizzate e disponibili per il decodificatore). Al momento non ho assolutamente idee per un approccio più efficiente, ma sono sicuro che esista. Ci penserò su nei prossimi giorni e forse proverò a giocare a golf su un lato, prima di aggiungere una spiegazione e tutto il resto.

Beh, almeno, ho dimostrato che è possibile ...

Alcuni script di CJam per il mio futuro riferimento:


51
Caro pete, cos'è questo.
Conor O'Brien,

2
Quanto tempo ci è voluto per farlo?
Adnan,

3
@AandN Ho giocato con i concetti per un "modello" generale da ieri di tanto in tanto (che non comportava alcun test effettivo ... scrivendo solo alcune cose su una griglia 7x7 e vedendo se poteva funzionare .. Probabilmente ho già scartato una mezza dozzina di approcci). La codifica vera e propria è durata stasera ... forse 3 ore, direi.
Martin Ender,

10
Le parole non possono spiegare quanto sono stupito quando vedo questo in azione con IDE esoterico passo dopo passo ... A chi potrebbe voler capire questo, questo esagono codifica la parte "decoder" in un numero intero che viene stampato con !e poi con un specchio /sull'ultima riga entra nel decodificatore per stampare il codice del decodificatore per completare il quine. Questo ha un uso miracoloso di <e >che legge il numero intero molto grande multilinea e ha creato l'area per la memorizzazione del decodificatore. Mi piacerebbe davvero sapere quali "dozzine di approcci" vengono prese in considerazione?
Sunny Pun

3
Spiegazione? ---
MD XF,

77

MySQL, 167 caratteri

SELECT REPLACE(@v:='SELECT REPLACE(@v:=\'2\',1+1,REPLACE(REPLACE(@v,\'\\\\\',\'\\\\\\\\\'),\'\\\'\',\'\\\\\\\'\'));',1+1,REPLACE(REPLACE(@v,'\\','\\\\'),'\'','\\\''));

Giusto. :-)

Ho davvero scritto questo da solo. È stato originariamente pubblicato sul mio sito .


72

GolfScript, 2 byte

1

(nota nuova riga finale) Questo spinge il numero 1 sulla pila. Alla fine del programma, GolfScript stampa tutti gli elementi nella pila (senza spazi tra di loro), quindi stampa una nuova riga.

Questo è un vero quine (come elencato nella domanda), perché esegue effettivamente il codice; non si limita a "leggere il file sorgente e stamparlo" (diversamente dall'invio di PHP).


Per un altro esempio, ecco un programma GolfScript per stampare 12345678:

9,(;
  1. 9: spingi 9 nello stack
  2. ,: consuma il 9 come argomento, spinge l'array [0 1 2 3 4 5 6 7 8]nello stack
  3. (: utilizza l'array come argomento, invia l'array [1 2 3 4 5 6 7 8]e l'oggetto 0nello stack
  4. ;: scarta l'elemento in cima alla pila

Lo stack ora contiene l'array [1 2 3 4 5 6 7 8]. Questo viene scritto nell'output standard senza spazi tra gli elementi, seguito da una nuova riga.


18
O PowerShell o PHP :-)
Joey,

6
Non sei tornato indietro nel tempo e hai dato all'inventore l'idea di inventare GolfScript, vero?
Mateen Ulhaq,

78
Tecnicamente, 1non è un gioco da ragazzi in GolfScript: emette 1\n, dove \ndenota una nuova riga. Tuttavia, il programma a due caratteri 1\n è un quine.
Ilmari Karonen,

17
\nProbabilmente anche il programma one-char è?
Lynn,

10
@Pseudonym a quine è letteralmente un programma che stampa la propria fonte. Non credo che ci siano restrizioni arbitrarie sulla "struttura".
Hugo Zink,

71

Brain-Flak , 9.8e580 1.3e562 9.3e516 12818 11024 4452 4332 4240 4200 4180 3852 3656 3616 3540 2485 + 3 = 2488 byte

Ora si adatta all'universo osservabile!

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()())([[]]){({}()<(([{}]())<{({}())<>(((((()()()()()){}){}){}())[()])<>{({}())<>{}({}(((()()()){}())){}{})<>{({}())<>({}(((()()()()()){})){}{}())<>{{}<>({}(((()()()()){}){}){})(<>)}}<>(({})[()()])<>}}{}<>({}(<()>)<><{({}<>)<>}<>>){({}<>)<>}{}(<>)<>{({}<>)<>}{}(((((((()()()()()){}){}){}))()))>){({}()<((({}[()])()))>)}{}<>{({}<>)<>}{}>)}{}<>{({}<>)<>}<>

Provalo online!


Spiegazione

Questo Quine funziona come la maggior parte dei Quines in lingue esoteriche; ha due parti un codificatore e un decodificatore. Il codificatore è tutte le parentesi all'inizio e il decodificatore è la parte più complessa alla fine.

Un modo ingenuo di codificare il programma sarebbe mettere nello stack il valore ASCII di ogni carattere nel decodificatore. Questa non è una buona idea perché Brain-Flak utilizza solo 8 caratteri ( ()<>[]{}), quindi si finisce per pagare parecchi byte per codificare pochissime informazioni. Un'idea più intelligente, e quella finora utilizzata è quella di assegnare ciascuna delle 8 parentesi graffe a un numero molto più piccolo (1-8) e convertirle in valori ASCII con il nostro decodificatore. Questo è carino perché non costa più di 18 byte per codificare un carattere rispetto al precedente 252.

Tuttavia, questo programma non fa nessuno dei due. Si basa sul fatto che i programmi Brain-Flak sono tutti bilanciati per codificare le 8 parentesi graffe con i numeri fino a 5. Le codifica come segue.

(       -> 2
<       -> 3
[       -> 4
{       -> 5
),>,],} -> 1

Tutte le parentesi chiuse sono assegnate 1 perché possiamo usare il contesto per determinare quale di esse dobbiamo usare in un particolare scenario. Questo può sembrare un compito scoraggiante per un programma Brain-Flak, ma in realtà non lo è. Prendiamo ad esempio le seguenti codifiche con le parentesi graffe decodificate e le parentesi chiuse sostituite con un .:

(.
((..
<([.{...

Spero che tu possa vedere che l'algoritmo è piuttosto semplice, leggiamo da sinistra a destra, ogni volta che incontriamo una parentesi graffa aperta spingiamo la sua parentesi graffa stretta a uno stack immaginario e quando incontriamo un .pop il valore più alto e lo mettiamo al posto del .. Questa nuova codifica ci consente di risparmiare un numero enorme di byte nel codificatore, perdendoci solo una manciata di byte sul decodificatore.

Spiegazione di basso livello

Lavori in corso


25
Penso che vincerai per la soluzione più lunga a una sfida di code-golf ...
Mego

18
Ho appena realizzato il più grande golf singolo nella storia di PPCG Nope. 9.8e580 è comunque impressionante.
Dennis,

19
+1 per adattarsi all'universo osservabile. Inoltre, con TIO Nexus, il permalink dovrebbe adattarsi alla risposta. tio.run/nexus/…
Dennis il

3
... golf molto grande ...
Limone distruttibile

3
Penso che vincerai per la maggior parte dei byte tagliati
Christopher,

68

Preludio , 5157 4514 2348 1761 1537 664 569 535 423 241 214 184 178 175 169 148 142 136 133 byte

Grazie a Sp3000 per aver salvato 3 byte.

Questo è piuttosto lungo ... (va bene, è ancora lungo ... almeno sta battendo il quint Brainfuck C # più breve conosciuto su questa sfida ora) ma è il primo quine che ho scoperto io stesso (i miei contributi Lua e Julia sono in realtà solo traduzioni di tecniche di quine standard in altre lingue) e per quanto ne so nessuno ha scritto un quine in Prelude finora, quindi sono davvero abbastanza orgoglioso di questo. :)

7( -^^^2+8+2-!( 6+ !
  ((#^#(1- )#)8(1-)8)#)4337435843475142584337433447514237963742423434123534455634423547524558455296969647344257)

Quel gran numero di cifre è solo una codifica del codice principale, motivo per cui il quine è così lungo.

Le cifre che codificano il quine sono state generate con questo script CJam .

Ciò richiede un interprete conforme allo standard, che stampa i caratteri (usando i valori come codici carattere). Quindi se stai usando l'interprete Python dovrai impostare NUMERIC_OUTPUT = False.

Spiegazione

Innanzitutto, alcune parole su Prelude: ogni riga in Prelude è una "voce" separata che manipola il proprio stack. Queste pile sono inizializzate su un numero infinito di 0 secondi. Il programma viene eseguito colonna per colonna, in cui tutti i comandi nella colonna vengono eseguiti "contemporaneamente" in base agli stati di stack precedenti. Le cifre vengono inserite nello stack individualmente, quindi 42spingono a 4, quindi a 2. Non c'è modo di spingere direttamente numeri più grandi, dovrai aggiungerli. I valori possono essere copiati da pile adiacenti con ve ^. I loop in stile Brainfuck possono essere introdotti con parentesi. Vedere il collegamento nel titolo per ulteriori informazioni.

Ecco l'idea di base del quine: prima spingiamo un sacco di cifre sullo stack che codificano il nucleo del quine. Detto nucleo prende quindi quelle cifre, le decodifica per stamparsi e quindi stampa le cifre come appaiono nel codice (e nel trascinamento )).

Ciò è leggermente complicato dal fatto che ho dovuto dividere il core su più linee. Inizialmente avevo la codifica all'inizio, ma poi avevo bisogno di riempire le altre linee con lo stesso numero di spazi. Questo è il motivo per cui i punteggi iniziali erano tutti così grandi. Ora ho messo la codifica alla fine, ma questo significa che prima devo saltare il core, quindi spingere le cifre e tornare indietro all'inizio e fare la stampa.

La codifica

Dal momento che il codice ha solo due voci, e l'adiacenza è ciclica ^e vsono sinonimi. Va bene perché vha di gran lunga il codice carattere più grande, quindi evitarlo usando sempre ^rende la codifica più semplice. Ora tutti i codici carattere sono compresi nell'intervallo da 10 a 94, inclusi. Questo significa che posso codificare ogni personaggio con esattamente due cifre decimali. Tuttavia, esiste un problema: alcuni caratteri, in particolare l'alimentazione di riga, hanno uno zero nella rappresentazione decimale. Questo è un problema perché gli zeri non sono facilmente distinguibili dal fondo dello stack. Fortunatamente c'è una soluzione semplice: compensiamo i codici dei caratteri di 2, quindi abbiamo un intervallo da 12 a 96, compreso, che si adatta comodamente a due cifre decimali. Ora di tutti i personaggi che possono apparire nel programma Prelude,0ha uno 0 nella sua rappresentazione (50), ma non ne abbiamo proprio bisogno 0. Quindi questa è la codifica che sto usando, spingendo ogni cifra singolarmente.

Tuttavia, poiché stiamo lavorando con uno stack, le rappresentazioni vengono spinte al contrario. Quindi, se osservi la fine della codifica:

...9647344257

Dividere in coppie e invertire, quindi sottrarre due e quindi cercare i codici carattere:

57 42 34 47 96
55 40 32 45 94
 7  (     -  ^

dove 32è corrisponde agli spazi. Il nucleo esegue esattamente questa trasformazione, quindi stampa i personaggi.

Il centro

Vediamo quindi come vengono effettivamente elaborati questi numeri. Innanzitutto, è importante notare che le parentesi corrispondenti non devono essere sulla stessa linea in Prelude. Può esserci solo una parentesi per colonna, quindi non c'è ambiguità in cui le parentesi si uniscono. In particolare, la posizione verticale della parentesi di chiusura è sempre irrilevante: lo stack che viene controllato per determinare se il loop termina (o viene saltato del tutto) sarà sempre quello che ha il (.

Vogliamo eseguire il codice esattamente due volte: la prima volta saltiamo il core e spingiamo tutti i numeri alla fine, la seconda volta eseguiamo il core. In effetti, dopo aver eseguito il core, invieremo nuovamente tutti quei numeri, ma poiché il loop termina in seguito, questo è irrilevante. Questo dà il seguente scheletro:

7(
  (                   )43... encoding ...57)

Innanzitutto, inseriamo 7a nella prima voce: se non lo facciamo, non entreremmo mai nel loop (per lo scheletro è importante solo che questo sia diverso da zero ... perché è quello 7che vedremo in seguito) . Quindi entriamo nel loop principale. Ora, la seconda voce contiene un altro loop. Al primo passaggio, questo ciclo verrà ignorato perché il secondo stack è vuoto / contiene solo 0 secondi. Quindi passiamo direttamente alla codifica e inseriamo tutte quelle cifre nello stack. L' 7abbiamo inserito nel primo stack è ancora lì, quindi il loop si ripete.

Questa volta, c'è anche un 7secondo stack, quindi inseriamo loop nella seconda voce. Il loop sulla seconda voce è progettato in modo tale che lo stack sia di nuovo vuoto alla fine, quindi funziona solo una volta. Sarà anche esaurire la prima pila ... Così, quando lasciamo il ciclo sul seconda voce, ci spinge ancora una volta tutte le cifre, ma ora il 7sulla prima pila è stata scartata, in modo che i principali capi di loop e il programma termina.

Quindi, diamo un'occhiata al primo loop nel core effettivo. Fare cose contemporaneamente con un (o )è abbastanza interessante. Ho segnato il corpo del loop qui con =:

-^^^2+8+2-!
(#^#(1- )#)
 ==========

Ciò significa che la colonna contenente (non è considerata parte del loop (i caratteri lì vengono eseguiti solo una volta e anche se il loop viene saltato). Ma la colonna che contiene ) è parte del ciclo e viene eseguita una volta per ogni iterazione.

Quindi iniziamo con un singolo -, che trasforma 7il primo stack in un -7... di nuovo, più in seguito. Per quanto riguarda il circuito reale ...

Il ciclo continua mentre la pila di cifre non è stata svuotata. Elabora due cifre alla volta. Lo scopo di questo loop è di decodificare la codifica, stampare il personaggio e allo stesso tempo spostare la pila di cifre sulla prima voce. Quindi prima questa parte:

^^^
#^#

La prima colonna sposta la cifra 1 sulla prima voce. La seconda colonna copia la cifra di 10 cifre nella prima voce mentre copia anche la cifra di 1 cifra nella seconda voce. La terza colonna riporta quella copia alla prima voce. Ciò significa che la prima voce ora ha 1 cifra due volte e la 10 cifra in mezzo. La seconda voce ha solo un'altra copia della 10 cifre. Ciò significa che possiamo lavorare con i valori in cima alle pile ed essere sicuri che ci siano due copie rimaste sulla prima pila per dopo.

Ora recuperiamo il codice carattere dalle due cifre:

2+8+2-!
(1- )#

Il fondo è un piccolo anello che riduce di 10 cifre a zero. Per ogni iterazione vogliamo aggiungere 10 all'inizio. Ricorda che il primo 2non fa parte del loop, quindi il corpo del loop è in realtà +8+2che aggiunge 10 (usando il 2push precedentemente) e lo spinge un altro 2. Quindi quando abbiamo finito con il loop, il primo stack ha effettivamente la base- 10 e un altro 2. Sottraiamo quel 2 con -per tenere conto dell'offset nella codifica e stampare il carattere con !. Il #giusto scarta lo zero alla fine del ciclo inferiore.

Una volta completato questo ciclo, il secondo stack è vuoto e il primo stack contiene tutte le cifre in ordine inverso (e una -7in fondo). Il resto è abbastanza semplice:

( 6+ !
8(1-)8)#

Questo è il secondo loop del core, che ora stampa indietro tutte le cifre. Per fare ciò abbiamo bisogno di 48 per ogni cifra per ottenere il codice carattere corretto. Lo facciamo con un semplice ciclo che esegue i 8tempi e aggiunge 6ogni volta. Il risultato viene stampato con !e 8alla fine è per la successiva iterazione.

E che dire del -7? Sì, 48 - 7 = 41che è il codice carattere di ). Magia!

Alla fine, quando abbiamo finito con quel loop, scartiamo quello con cui 8abbiamo appena spinto #per assicurarci di lasciare il loop esterno sulla seconda voce. Inseriamo nuovamente tutte le cifre e il programma termina.



19
Martin, devi fermarti da qualche parte.
Seequ,

3
Adoro il fatto che questo abbia oltre 5000 byte giocati a golf, oltre a un riconoscimento a Sp3000 per averne salvati 3.
Kamil Drakari,

2
@KamilDrakari Questi erano gli ultimi 3 byte, quindi è un grosso problema. ;)
Martin Ender

57

Esagonia , lunghezza lato 11, 314 byte

164248894991581511673077637999211259627125600306858995725520485910920851569759793601722945695269172442124287874075294735023125483.....!/:;.........)%'=a':\....................\...................\..................\.................\................\...............\..............\..$@.........\$><>'?2='%.<\:;_;4Q

Provalo online!


Versione precedente:

Esagonia , lunghezza lato 11, 330 byte

362003511553420961423766261426252539048636523959468260999944549820033581478284471415809677091006384959302453627348235790194699306179..../:{;+'=1P'%'a{:..\.....................\...................\..................\.................\................\...............\..............\.............\!$><........\..@>{?2'%<......:;;4Q/

Provalo online!

Encoder: provalo online!

Il programma è approssimativamente equivalente a questo codice Python: provalo online!

Codice non spiegato:

           3 6 2 0 0 3 5 1 1 5 5
          3 4 2 0 9 6 1 4 2 3 7 6
         6 2 6 1 4 2 6 2 5 2 5 3 9
        0 4 8 6 3 6 5 2 3 9 5 9 4 6
       8 2 6 0 9 9 9 9 4 4 5 4 9 8 2
      0 0 3 3 5 8 1 4 7 8 2 8 4 4 7 1
     4 1 5 8 0 9 6 7 7 0 9 1 0 0 6 3 8
    4 9 5 9 3 0 2 4 5 3 6 2 7 3 4 8 2 3
   5 7 9 0 1 9 4 6 9 9 3 0 6 1 7 9 . . .
  . / : { ; + ' = 1 P ' % ' a { : . . \ .
 . . . . . . . . . . . . . . . . . . . . \
  . . . . . . . . . . . . . . . . . . . \ 
   . . . . . . . . . . . . . . . . . . \  
    . . . . . . . . . . . . . . . . . \   
     . . . . . . . . . . . . . . . . \    
      . . . . . . . . . . . . . . . \     
       . . . . . . . . . . . . . . \      
        . . . . . . . . . . . . . \       
         ! $ > < . . . . . . . . \        
          . . @ > { ? 2 ' % < . .         
           . . . . : ; ; 4 Q / .          

Due .secondi richiedono 1 bit. Qualsiasi altro carattere richiede 1 bit e una cifra di 97 base.

Spiegazione

Clicca sulle immagini per ingrandirle. Ogni parte della spiegazione ha il codice Python corrispondente per aiutare la comprensione.

Parte dei dati

Al posto della struttura complessa utilizzato in alcune altre risposte (con <, "e alcune altre cose), ho appena lasciato passare il IP attraverso la metà inferiore.

Dati

Innanzitutto, l'IP scorre molti numeri e no-op's ( .) e mirrors ( \). Ogni cifra viene aggiunta al numero in memoria, quindi alla fine il valore della memoria è uguale al numero all'inizio del programma.

mem = 362003511...99306179

! lo stampa,

stdout.write(str(mem))

e $passa alla successiva >.

A partire dal <. Se il valore della memoria memè errato ( <= 0cioè la condizione mem > 0non è soddisfatta), abbiamo finito di stampare il programma e dovremmo uscire. L'IP seguirà il percorso superiore.

Uscita

(lascia che l'IP scorra in tutto il mondo per circa 33 comandi prima di premere il @(che termina il programma) perché posizionandolo in qualsiasi altro posto comporta dei byte aggiuntivi)

Se è vero, seguiamo il percorso inferiore, veniamo reindirizzati alcune volte ed eseguiamo altri comandi prima di colpire un altro condizionale.

# Python                    # Hexagony
# go to memory cell (a)     # {
a = 2                       # ?2
# go to memory cell (b)     # '
b = mem % a                 # %

Ora il ricordo è simile al seguente:

Mem1

Se il valore è vero:

if b > 0:

viene eseguito il seguente codice:

# Python                    # Hexagony
b = ord('Q')                # Q
b = b*10+4                  # 4
# Note: now b == ord('.')+256*3
stdout.write(chr(b%256))    # ;
stdout.write(chr(b%256))    # ;

Vedi spiegazione dettagliata del Q4a risposta HelloWorld Hexagony di MartinEnder . In breve, questo codice viene stampato .due volte.

Inizialmente avevo programmato di stampare .una volta. Quando ho pensato a questo (stampare .due volte) e implementarlo, sono state salvate circa 10 cifre.

Poi,

b = mem // a                # :

Ecco un fatto importante che mi sono reso conto che mi ha salvato circa 14 cifre: non è necessario essere da dove hai iniziato.


Per capire cosa sto dicendo, facciamo un'analogia BF. (salta questo se hai già capito)

Dato il codice

while a != 0:
    b, a = a * 2, 0
    a, b = b, 0
    print(a)

Supponendo che lasciamo aessere il valore della cella corrente e bil valore della cella giusta, una traduzione diretta di questo in BF è:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
    >[-<+>]       # a, b = b, 0
    <.            # print(a)
]

Tuttavia, durante il programma non è necessario essere sempre nella stessa posizione. Possiamo lasciare che il valore di aqualunque cosa siamo all'inizio di ogni iterazione, quindi abbiamo questo codice:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
                  # implicitly let (a) be at the position of (b) now
    .             # print(a)
]

che è più breve di diversi byte.


Inoltre, il comportamento di avvolgimento degli angoli mi evita anche di avere uno \specchio lì - senza di esso non sarei in grado di adattare le cifre (+2 cifre per \se stessa e +2 cifre per un spaiato .alla sua destra, per non parlare del bandiere)

(dettagli:

  • L'IP entra nell'angolo in basso a sinistra, andando a sinistra
  • Si deforma nell'angolo destro, continua ancora a sinistra
  • Incontra un \che lo riflette, ora si dirige verso l'alto
  • Va in un angolo e si deforma di nuovo nell'angolo in basso a sinistra

)


Se il valore (dell'operazione mod 2 sopra) è errato (zero), seguiamo questo percorso:

# Python                 # Hexagony   # Memory visualization after execution
b = mem // a             # :          # click here
base = ord('a') # 97     # a
y = b % base             # '%
offset = 33              # P1
z = y + offset           # ='+
stdout.write(chr(z))     # ;          # click here
mem = b // base          # {:         # click here

Non spiegherò troppo in dettaglio qui, ma l'offset in realtà non è esattamente 33, ma è congruente al 33mod 256. E chrha un implicito % 256.


3
Amico, questo è un sacco di no-ops
Jo King,

26
Ho riso di "Per capire cosa sto dicendo, facciamo un'analogia [BrainFuck]." Solo su PPCG ... :)
Lynn,

2
Ho fatto scorrere 3 volte in cima alla risposta per votarla, solo per scoprire che l'ho già fatto ...
NieDzejkob,

2
310 byte sfruttando il nuovo spazio dall'accorciamento del numero
Jo King,

2
308 byte eliminando ancora più spazio
Jo King,

46

Vim, 11 byte

q"iq"qP<Esc>hqP
  • iq"qP<Esc>: Inserire manualmente un duplicato del testo che deve essere esterno alla registrazione.
  • q"e hqP: registra l'interno direttamente nel ""registro senza nome , in modo che possa essere incollato nel mezzo. L' hè l'unico riposizionamento richiesto; se lo metti nella macro, verrà incollato nel risultato.

modificare

Una nota sulla registrazione con q": Il registro senza nome ""è una cosa divertente. Non è proprio un vero registro come gli altri, poiché il testo non è memorizzato lì. In realtà è un puntatore ad un altro registro (di solito "-per le eliminazioni senza una nuova riga, "0per gli yank o "1per le eliminazioni con una nuova riga). q"infrange le regole; in realtà scrive "0. Se hai ""già indicato un registro diverso da "0, q"sovrascriverà "0ma rimarrà ""invariato. Quando avvii un nuovo Vim, ""punta automaticamente a "0, quindi stai bene in quel caso.

Fondamentalmente, Vim è strano e pieno di bug.


aspetta perché questo non funziona per me
Destructible Lemon

@DestructibleWatermelon Non posso dirlo con certezza, ma una spiegazione è molto probabile. Probabilmente avrebbe dovuto averlo scritto prima, dal momento che può allontanare la gente. Leggi la modifica.
icaica,

dovresti probabilmente mettere qualcosa su come ypuò essere utile premere o qualcosa prima di correre
Limone distruttibile

Perché non usi per mostrare premendo il tasto <Esc>? Parte di questo blocco Unicode "Control Pictures"
mbomb007,

4
@ mbomb007 La <Esc>notazione è standard nelle mappature Vim ( :help <>) ed è quello che utilizza vimgolf.com. Qualsiasi vimgolfer esperto verrà utilizzato per leggerlo. Per quanto riguarda l'unicode, devo socchiudere gli occhi per leggere le lettere minuscole, che oscurano il metodo di digitarle e cercare il file della guida.
icaica,

44

Cubix , 20 byte

3434Qu$v@!<"OOw\o;/"

Quasi ottenuto il \o/ ...

Netto :

    3 4
    3 4
Q u $ v @ ! < "
O O w \ o ; / "
    . .
    . .

Provalo online

Provalo qui !

Note aggiuntive

Storia di fondo

Dopo essere stato colpito dalla lettura di questa grande risposta di @ ais523, ho iniziato a pensare di continuare a giocare a golf con le quine. Dopotutto, c'erano un bel po 'di cose da fare, e questo non sembrava molto compresso. Tuttavia, poiché la tecnica utilizzata dalla sua risposta (e anche dalla mia) richiede che il codice si estenda su righe complete, è necessario un risparmio di almeno 12 byte. C'era un'osservazione nella sua spiegazione che mi ha fatto davvero pensare:

Per quanto riguarda il golf lungo questo campo, [...] avrebbe bisogno [...] di un altro modo di rappresentare la faccia superiore del cubo [...]

Poi, all'improvviso, mentre mi alzavo e mi allontanavo per prendere qualcosa da bere, mi ha colpito: cosa sarebbe successo se il programma non avesse usato i codici carattere, ma piuttosto i numeri per rappresentare la faccia superiore? Questo è particolarmente breve se il numero che stiamo stampando ha 2 cifre. Cubix dispone di 3 istruzioni a un byte per spingere i numeri a due cifre: N, Se Qche spingono 10, 32e 34, rispettivamente, quindi questo dovrebbe essere abbastanza Golfy, ho pensato.

La prima complicazione con questa idea è che la faccia superiore è ora piena di numeri inutili, quindi non possiamo più usarla. La seconda complicazione è che la faccia superiore ha una dimensione quadrata del cubo, e doveva avere una dimensione pari, altrimenti un numero finirebbe anche sulla posizione iniziale del puntatore dell'istruzione, portando a una pila inquinata. A causa di queste complicazioni, il mio codice doveva adattarsi a un cubo di dimensione 2 (che può contenere "solo" 24 byte, quindi ho dovuto golf su almeno 21 byte). Inoltre, poiché le facce superiore e inferiore sono inutilizzabili, avevo solo 16 byte effettivi.

Quindi ho iniziato scegliendo il numero che sarebbe diventato la metà della faccia superiore. Ho iniziato con N(10), ma non ha funzionato del tutto a causa dell'approccio che stavo adottando per stampare tutto. Ad ogni modo, ho iniziato di nuovo e ho usato S(32) per qualche motivo. Ciò ha comportato un vero quine, o almeno così pensavo. Tutto ha funzionato molto bene, ma mancavano le citazioni. Poi, mi è venuto in mente che il Q(34) sarebbe stato davvero utile. Dopotutto, 34 è il codice carattere della virgoletta doppia, che ci consente di tenerlo in pila, salvando (2, nel layout che ho usato allora) byte preziosi. Dopo aver modificato un po 'il percorso IP, tutto ciò che mi restava era un esercizio per riempire gli spazi vuoti.

Come funziona

Il codice può essere suddiviso in 5 parti. Li esaminerò uno per uno. Si noti che stiamo codificando le facce intermedie in ordine inverso perché il modello di stack è il primo all'ultimo.

Passaggio 1: stampare la faccia superiore

Le istruzioni irrilevanti sono state sostituite da no-ops ( .). L'IP inizia la terza riga, all'estrema sinistra, puntando verso est. Lo stack è (ovviamente) vuoto.

    . .
    . .
Q u . . . . . .
O O . . . . . .
    . .
    . .

L'IP termina nella posizione più a sinistra sulla quarta riga, puntando verso ovest, per avvolgersi nella posizione più a destra sulla stessa linea. Le istruzioni eseguite sono (senza il carattere del flusso di controllo):

QOO
Q   # Push 34 (double quotes) to the stack
 OO # Output twice as number (the top face)

Lo stack contiene solo 34, che rappresentano l'ultimo carattere della fonte.

Passaggio 2: codifica la quarta riga

Questo bit fa praticamente quello che ti aspetti che faccia: codifica la quarta riga. L'IP inizia con la virgoletta doppia alla fine di quella riga e va verso ovest mentre spinge i codici dei caratteri di ogni personaggio su cui si trova fino a quando non trova una doppia virgoletta corrispondente. Questa virgoletta doppia corrispondente è anche l'ultimo carattere della quarta riga, poiché l'IP si avvolge di nuovo quando raggiunge il bordo sinistro.

In effetti, l'IP ha spostato una posizione a sinistra e lo stack ora contiene la rappresentazione della quarta riga in codici carattere e ordine inverso.

Passaggio 3: invia un'altra citazione

Dobbiamo spingere un'altra citazione, e quale modo migliore di riciclare Qall'inizio del programma avvicinandolo da destra? Questo ha l'ulteriore vantaggio che l'IP si imbatte direttamente nel preventivo che codifica la terza riga.

Ecco la versione netta per questo passaggio. Le istruzioni irrilevanti sono state nuovamente sostituite da operazioni non operative, le operazioni non operative eseguite sono state sostituite da hashtag ( #) a scopo illustrativo e l'IP inizia dall'ultimo carattere sulla quarta riga.

    . .
    . .
Q u $ . . . . .
. . w \ . . / .
    . #
    . #

L'IP termina sulla terza riga alla prima istruzione, sta per finire alla fine di quella linea perché punta verso ovest. Vengono eseguite le seguenti istruzioni (escluso il flusso di controllo):

$uQ
$u  # Don't do anthing
  Q # Push the double quote

Questa doppia virgoletta rappresenta quella alla fine della terza riga.

Passaggio 4: codifica della terza riga

Funziona esattamente come il passaggio 2, quindi per favore guarda lì per una spiegazione.

Passaggio 5: stampare la risma

Lo stack ora contiene la quarta e la terza riga, in ordine inverso, quindi tutto ciò che dobbiamo fare ora, lo stampa. L'IP inizia alla penultima istruzione sulla terza riga, spostandosi verso ovest. Ecco la parte rilevante del cubo (di nuovo, le parti non pertinenti sono state sostituite da no-ops).

    . .
    . .
. . . v @ ! < .
. . . \ o ; / .
    . .
    . .

Questo è un ciclo, come potresti aver visto / previsto. Il corpo principale è:

o;
o  # Print top of stack as character
 ; # Delete top of stack

Il ciclo termina se l'elemento in alto è 0, che si verifica solo quando lo stack è vuoto. Se il ciclo termina, @viene eseguito, terminando il programma.


vorrei poter
votare di

I doni sono sempre ben accetti ;-)
Luca

42

Javascript ES6 - 21 byte

$=_=>`$=${$};$()`;$()

Io chiamo questo quine "The Bling Quine".

A volte, devi giocare a golf con stile.


Ti fa !$=_=>`!$=${$}()`()risparmiare 2 byte?
Downgoat,

Invalid assignment left hand side. Vorrei che funzionasse :(
Mama Fun Roll,

1
@ TùxCräftîñg che elimina le parentesi attorno ai letterali dei template funziona solo su funzioni prototipo native, come Array.prototype.join.
Mama Fun Roll,

2
Hmm, non ne sono sicuro. L'ho scritto più di un anno fa (era considerato valido allora), e non ho seguito troppo da vicino le modifiche alle regole. Tuttavia, aggiungendo alerto console.logdopo la funzione freccia e avvolgendo la stringa del modello tra parentesi funzionerebbe.
Mama Fun Roll

3
Inoltre, se lo esegui nel concole, sovrascrive $ (funzione jQuery) su questo sito e la funzione upvote non funzionerà più. :)
Steven Palinkas,

41

Brainf * ck (755 caratteri)

Questo si basa su una tecnica sviluppata da Erik Bosman (ejbosman su cs.vu.nl). Si noti che "ESultanik's Quine!" il testo è effettivamente necessario per essere un quine!

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>++>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>>+++++++++++++++>+++++++++++++>++++++>+++++++++++++++>++++++++++>+++>+++>++++>++++++++++++++>+++>++++++++++>++++>++++++>++>+++++>+++++++++++++++>++++++++>++++>++++++++++++>+++++++++++++++>>++++>++++++++++++++>+++>+++>++++>++++++>+++>+++++++++>++++>+>++++>++++++++++>++++>++++++++>++>++++++++++>+>+++++++++++++++>+++++++++++++
ESultanik's Quine!
+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++++>]<.<-<]

13
Questo è un modo intelligente per farlo.
Peter Olson,

13
Come funziona?
orgoglioso haskeller il

3
@proudhaskeller IIRC, la parte precedente ESultanik's Quine!imposta la memoria come codifica di stack ESultanik's Quine!e successive, con due byte di memoria per ciascun carattere (offset del valore ASCII da 0x1F). L'ultimo bit di codice scorre nella memoria, riproducendo prima i ++>+++…codici per ciascun carattere, quindi stampando effettivamente i caratteri.
ESultanik,

4
@CatsAreFluffy Sono necessari per essere un quine! Mentre è vero che potrebbero essere rimossi, si dovrebbe anche cambiare il codice precedente per mantenere la proprietà quine.
ESultanik,

1
È vero. Anche le newline sono necessarie.
Calcolatrice

36

Esagonia , lunghezza laterale 15 14 13 12, 616 533 456 383 byte

Dopo diversi giorni di golf accurato, riorganizzare i circuiti e ricominciare, sono finalmente riuscito a farlo scendere a un esagono laterale 12.

1845711724004994017660745324800783542810548755533855003470320302321248615173041097895645488030498537186418612923408209003405383437728326777573965676397524751468186829816614632962096935858"">./<$;-<.....>,.........==.........<"......."">'....>+'\.>.........==........<"......"">:>)<$=<..>..............$..<"...."">\'Q4;="/@>...............<"....."">P='%<.>.............<"..!'<.\=6,'/>

Provalo online!

non piegato:

            1 8 4 5 7 1 1 7 2 4 0 0
           4 9 9 4 0 1 7 6 6 0 7 4 5
          3 2 4 8 0 0 7 8 3 5 4 2 8 1
         0 5 4 8 7 5 5 5 3 3 8 5 5 0 0
        3 4 7 0 3 2 0 3 0 2 3 2 1 2 4 8
       6 1 5 1 7 3 0 4 1 0 9 7 8 9 5 6 4
      5 4 8 8 0 3 0 4 9 8 5 3 7 1 8 6 4 1
     8 6 1 2 9 2 3 4 0 8 2 0 9 0 0 3 4 0 5
    3 8 3 4 3 7 7 2 8 3 2 6 7 7 7 5 7 3 9 6
   5 6 7 6 3 9 7 5 2 4 7 5 1 4 6 8 1 8 6 8 2
  9 8 1 6 6 1 4 6 3 2 9 6 2 0 9 6 9 3 5 8 5 8
 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
           ! ' < . \ = 6 , ' / > . .
            . . . . . . . . . . . .

Sebbene non sembri il più esagerato del codice Hexagony, il tipo di codifica che ho usato è ottimizzato per le corse più lunghe di no-op, cosa che altrimenti eviteresti.

Spiegazione

Questo batte la precedente risposta Hexagony codificando il no-ops ( .) in un modo diverso. Mentre quella risposta consente di risparmiare spazio rendendo ogni altro personaggio a ., il mio codifica il numero di operazioni non consentite. Significa anche che la fonte non deve essere così limitata.

Qui uso una codifica di base 80, in cui i numeri inferiori a 16 indicano serie di operazioni non operative e numeri compresi tra 16 e 79 rappresentano l'intervallo da 32 ( !) a 95 ( _) (sto solo realizzando che ho giocato a golf tutti _i codice lol). Alcuni pseudocodici Pythonic:

i = absurdly long number
print(i)
base = 80
n = i%base
while n:
    if n < 16:
        print("."*(16-n))
    else:
        print(ASCII(n+16))
    i = i//base
    n = i%base

Il numero è codificato nella prima metà dell'esagono, con tutto il

" " > 
 " " > 
  ... etc

sul lato sinistro e il

 > ,
< "
 >
< "
... etc

sul lato destro reindirizzando il puntatore per codificare il numero in una cella. Questo è tratto dalla risposta di Martin Ender (grazie), perché non sono riuscito a trovare un modo più efficiente.

Entra quindi nella sezione inferiore attraverso ->:

       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
     ->    ! ' < . \ = 6 , ' / > . .

!stampa il numero e 'passa alla cella di memoria corretta prima di iniziare il ciclo. P='%modifica il numero corrente di 80. Se il risultato è 0, vai su fino alla fine @, altrimenti vai giù e crea una cella accanto al risultato mod con il valore -16.

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
                      /
                     /

Imposta la cella su (valore mod + -16). Se quel valore è negativo, sali alla diramazione >+'\, altrimenti scendi.

Se il valore è positivo:

 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .

Il puntatore finisce in corrispondenza del ;-<quale imposta la cella su (valore mod - -16) e la stampa.

Il valore è negativo:

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .

Passa alla > ) <sezione che avvia il loop. Qui è isolato:

     . . > ) < $ = < . .
      . . . . . . . . .
       \ ' Q 4 ; = " /

Che esegue il codice 'Q4;="=che stampa un .(grazie ancora a Martin Ender, che ha scritto un programma per trovare le combinazioni di lettere e numeri per i caratteri) e torna alla cella iniziale. Quindi incrementa ( )) la cella del valore mod e lo fa nuovamente, fino a quando il valore mod non è positivo.

Al termine, si sposta verso l'alto e si unisce all'altra sezione in:

 " " > . / < $ ; - < . . .
            \
             \

Il puntatore torna quindi all'inizio del ciclo più grande

 " " > . / <--
  . . . = =
   . " " > ' 
    . . . = = 
     . " " > :
      . . . . .
       " " > \ ' . .
        . . . . . . .
         . . " " > P = ' % < . > . . .

Questo esegue ='=:'che divide il numero corrente per 80 e passa alla cella corretta.

Vecchia versione (Lunghezza lato 13)

343492224739614249922260393321622160373961419962223434213460086222642247615159528192623434203460066247203920342162343419346017616112622045226041621962343418346002622192616220391962343417346001406218603959366061583947623434"">/':=<$;'<.....>(......................<"......"">....'...>=\..>.....................<"....."">....>)<.-...>...........==......<"...."">.."...'.../>.................<"..."">\Q4;3=/.@.>...............<".."".>c)='%<..>..!'<.\1*='/.\""

Provalo online!

Posso sicuramente giocare a golf su un altro lato, ma dovrò lasciarlo fino a domani perché si sta facendo tardi. Ho scoperto che sono impaziente e non vedo l'ora che arrivi domani. Forse un altro lato può essere giocato a golf? :( ahhhhhhhhh l' ho fatto!

Ho anche giocato a un paio di cifre extra con una codifica 77 di base, ma non importa, dal momento che ha lo stesso numero di byte.


13
Questo è fantastico L'idea per questa codifica ibrida di lunghezza normale è davvero chiara. :) Ricordami di darti una taglia se dimentico.
Martin Ender,

35

PostScript, 20 caratteri

Breve e legittimo. 20 caratteri incluso newline finale.

(dup == =)
dup == =

33

Cubix , 45 byte

.....>...R$R....W..^".<R.!'.\)!'"R@>>o;?/o'u"

Puoi testare questo codice qui .

Questo programma è abbastanza difficile da seguire, ma per avere qualche possibilità di farlo, dobbiamo iniziare espandendolo in un cubo, come fa l'interprete Cubix:

      . . .
      . . >
      . . .
R $ R . . . . W . . ^ "
. < R . ! ' . \ ) ! ' "
R @ > > o ; ? / o ' u "
      . . .
      . . .
      . . .

Questo è un quine in stile Befunge, che funziona sfruttando il wrapping per rendere i letterali stringa "avvolgere" il codice eseguibile (con un solo "segno, il codice è sia dentro che fuori dal preventivo allo stesso tempo, qualcosa che diventa possibile quando si ha programmi non lineari e non planari). Si noti che questo si adatta alla nostra definizione di un vero quine, perché due delle doppie virgolette non si codificano da sole, ma piuttosto vengono calcolate in seguito tramite l'uso dell'aritmetica.

A differenza di Befunge, tuttavia, stiamo usando quattro stringhe qui, anziché una. Ecco come vengono spinti nello stack;

  1. Il programma inizia nella parte superiore del bordo sinistro, andando verso destra; gira a destra due volte ( R), facendolo andare verso sinistra lungo la terza e ultima delle linee che avvolgono l'intero cubo. La virgoletta doppia corrisponde a se stessa, quindi spingiamo l'intera terza riga sulla pila all'indietro. Quindi l'esecuzione continua dopo la doppia citazione.

  2. Il ucomando fa un'inversione a U verso destra, quindi la prossima cosa che stiamo eseguendo è da in '"poi sulla linea di mezzo. Questo spinge a "sulla pila. Continuando a avvolgere, colpiamo il <lato sinistro del cubo e rimbalziamo indietro. Quando ci avviciniamo da questa direzione, vediamo un "comando semplice , no '", quindi l'intera seconda riga viene spinta sullo stack all'indietro sopra la terza riga e la doppia virgoletta.

  3. Iniziamo spingendo a !sullo stack ( '!) e aumentandolo ( )); questo produce una doppia virgoletta senza bisogno di una doppia virgoletta nel nostro codice sorgente (che terminerebbe la stringa). Un mirror ( \) riflette la direzione di esecuzione verso nord; quindi il Wcomando evita a sinistra. Questo ci lascia andare verso l'alto sulla settima colonna, che poiché si tratta di un cubo, si sposta verso sinistra sulla terza riga, quindi verso il basso sulla terza colonna. Premiamo un R, per girare a destra e andare a sinistra lungo la fila superiore; quindi $salta la Rvia attraverso la quale siamo entrati nel programma, quindi l'esecuzione "termina alla fine della riga e catturiamo la prima riga in una stringa come abbiamo fatto per la seconda e la terza.

  4. Il ^comando ci manda verso nord sull'undicesima colonna, che è (permettendo l'avvolgimento del cubo) verso sud sulla quinta. L'unica cosa che incontriamo è !(salta se diverso da zero; la parte superiore della pila è effettivamente diversa da zero), che salta il ocomando, rendendo effettivamente vuota la quinta colonna. Quindi torniamo al ucomando, che ancora una volta gira a U, ma questa volta restiamo sull'ultima colonna verso sud, che si sposta sulla quarta colonna verso nord. Durante l'inversione a U, tuttavia, facciamo una doppia virgoletta, quindi catturiamo l'intera quarta colonna in una stringa, dal basso verso l'alto. A differenza della maggior parte delle doppie virgolette nel programma, questa non si chiude da sola; piuttosto, è chiuso dal "nell'angolo in alto a destra, il che significa che catturiamo la stringa di nove caratteri ...>......

Quindi il layout dello stack è ora, dall'alto verso il basso: quarta colonna; riga superiore; "; fila centrale; "; riga inferiore. Ognuno di questi è rappresentato nella pila con il primo carattere più vicino alla cima della pila (Cubix spinge le stringhe al contrario di questo ordine, come fa Befunge, ma ogni volta che l'IP si muoveva nella direzione opposta alla direzione di lettura naturale, quindi è stato effettivamente invertito due volte). Si può notare che i contenuti dello stack sono quasi identici al programma originale (perché la quarta colonna e la faccia nord / superiore del cubo contengono gli stessi caratteri nello stesso ordine; ovviamente, è stato progettato intenzionalmente).

Il prossimo passo è stampare il contenuto della pila. Dopo tutte le spinte, l'IP sta andando verso nord sulla quarta colonna, quindi colpisce >lì ed entra in un circuito stretto >>o;?(cioè "gira a est, gira a est, uscita come carattere, pop, gira a destra se positivo"). Poiché la settima riga è piena di NOP, ?tornerà alla prima >, quindi questo spinge efficacemente l'intero contenuto dello stack ( ?è una no-op su uno stack vuoto). Abbiamo quasi stampato l'intero programma! Sfortunatamente, non è ancora del tutto fatto; ci manca la doppia virgoletta alla fine.

Una volta terminato il ciclo, riflettiamo sulla linea centrale, spostandoci verso ovest, attraverso una coppia di specchi. (Abbiamo usato "l'altro lato" dello \specchio prima; ora stiamo usando il lato sud-ovest. Lo /specchio non è mai stato usato prima.) Ci incontriamo '!, quindi spingiamo un punto esclamativo (cioè 33; stiamo usando ASCII e Cubix non distingue tra numeri interi e caratteri) nello stack. (Convenientemente, questo è lo stesso !che è stato usato per saltare il ocomando in precedenza.) Incontriamo una coppia di Rcomandi e li usiamo per fare un'inversione a U "manuale" (il secondo Rcomando qui è stato usato prima per raggiungere il primo riga, quindi mi è sembrato più naturale adattarsi a un altro Rcomando al suo fianco.Wcomando, per eludere a sinistra. Il sidestep si arresta nel >comando direttamente sulla seconda riga, rimbalzando l'esecuzione esattamente dove si trovava. Quindi evitiamo di nuovo a sinistra, ma questa volta andiamo verso sud, quindi il comando successivo da eseguire è )(incrementando il punto esclamativo in una doppia virgoletta), seguito da un o(per emetterlo). Infine, l'esecuzione termina lungo l'ottava riga fino alla seconda colonna, dove trova a @per uscire dal programma.

Mi scuso per l'apostrofo randagio sulla terza riga. Non fa nulla in questa versione del programma; faceva parte di un'idea precedente che avevo ma che si rivelò non necessaria. Tuttavia, una volta che ho ottenuto un quine funzionante, volevo solo inviarlo piuttosto che cercarlo ulteriormente, soprattutto perché rimuoverlo non cambierebbe il conteggio dei byte. A proposito di giocare a golf su questo quine ulteriormente, non mi sorprenderebbe se ciò fosse possibile a 3 × 3 usando solo le prime cinque righe, ma non riesco a vedere un modo ovvio per farlo, e avrebbe bisogno un impacchettamento ancora più stretto di tutto il flusso di controllo insieme ad un altro modo per rappresentare la faccia superiore del cubo (oppure modificando l'algoritmo in modo che possa continuare a usare la quarta colonna anche se ora avrebbe una lunghezza di dieci o undici caratteri) .


Bel lavoro, questo è un punteggio davvero impressionante. Adoro come hai codificato la faccia superiore. :)
Martin Ender il

Questo è semplicemente incredibile! Se fosse di aiuto, un altro modo di spingere "è Q.
ETHproductions

1
Wow! Non avrei mai pensato di vedere un cubix quine!
FlipTack

3
Ieri non ho avuto il tempo di leggere la spiegazione, ma ora che ho ... Solo ... WOW. Non riesco a credere a quanti personaggi vengano usati per due o anche tre scopi completamente diversi. Questo è probabilmente il programma Cubix più bello che abbia mai visto.
ETHproductions

Buona spiegazione
Robert Fraser,

33

Python 2, 30 byte

_='_=%r;print _%%_';print _%_

Tratto da qui


1
+1, hai battuto la mia soluzione simile quindi l'ho eliminata. Va notato che questo funziona solo in Python 2.
nyuszika7h

2
Sembra strano con il nome della variabile come _, ma si legge meglio se lo si assegna a qualsiasi lettera, cioè s:s='s=%r;print s%%s';print s%s
Ehtesh Choudhury

5
Se questa soluzione non è una tua creazione, dovresti renderla Community Wiki. Inoltre, il collegamento è morto.
mbomb007,

1
Sono un po 'in ritardo alla festa, ma qualcuno può spiegare come funziona?
MadTux,

9
Ciò richiede che un avanzamento riga finale sia valido. Allo stato attuale, il codice sorgente non corrisponde all'output.
Dennis,

32

Tasti Vim, 17 , 14

Qualcuno lo ha casualmente votato, quindi mi sono ricordato che esiste. Quando l'ho riletto, ho pensato "Ehi, posso fare di meglio!", Quindi ho perso due byte. Non è ancora il più breve, ma almeno è un miglioramento.


Per molto tempo, mi chiedevo se fosse possibile un Vim Quine. Da un lato, deve essere possibile, poiché vim è in fase di completamento. Ma dopo aver cercato un vim quine per molto tempo, non sono riuscito a trovarne uno. Io ho trovato questa sfida PPCG , ma è chiuso e non quines esattamente su letterali. Così ho deciso di crearne uno, dal momento che non riuscivo a trovarne uno.

Sono davvero orgoglioso di questa risposta, a causa di due primati :

  1. Questo è il primo quine che abbia mai fatto, e

  2. Per quanto ne so, questo è il primo vim-quine al mondo ad essere mai pubblicato! Potrei sbagliarmi, quindi se ne conosci uno, per favore fatemelo sapere.

Quindi, dopo quella lunga introduzione, eccola qui:

qqX"qpAq@q<esc>q@q

Provalo online!

Si noti che quando si digita questo, verrà visualizzato il <esc>tasto come ^[. Questo è ancora accurato, poiché ^[rappresenta 0x1B, che è fuga in ASCII , e il modo in cui vim rappresenta internamente la <esc>chiave.

Si noti inoltre che il test potrebbe non riuscire se si carica una sessione vim esistente. Ho scritto una risposta di spiegando che qui , se si desidera ulteriori informazioni, ma fondamentalmente è necessario avviare VIM con

vim -u NONE -N -i NONE

o digitare qqqprima di eseguire questo.

Spiegazione:

qq                  " Start recording into register 'q'
  X                 " Delete one character before the cursor (Once we play this back, it will delete the '@')
   "qp              " Paste register 'q'
      Aq@q<esc>     " Append 'q@q' to this line
               q    " Stop recording
                @q  " Playback register 'q'

In una nota a margine, questa risposta è probabilmente un record mondiale per la maggior parte dei "q" in una risposta PPCG o qualcosa del genere.


1
2i2i<esc>è così vicino. Sento che ci deve essere qualcosa che posso fare per farlo funzionare.
Zwei

@zwei lo so, è vicino fa male! In realtà, <Esc>è implicito in V, quindi funziona . Purtroppo aggiunge anche una nuova riga, motivo per cui non l'ho ancora pubblicato.
DJMcMayhem

q"iq"qbP<Esc>qbPè 11. Dopo aver messo questo su reddit , ho studiato il vimgolfing qui e ho deciso di fare un account. Questa è la risposta che ho pubblicato lì.
icaica,

2
@udioica Puoi pubblicarlo come risposta?
DJMcMayhem

28

Perso , 120 116 98 96 76 70 66 byte

Modifica: yay, meno di 100

Modifica: salvato un sacco di byte passando a tutti i /s nella riga inferiore

:2+52*95*2+>::1?:[:[[[[@^%?>([ "
////////////////////////////////

Provalo online! + la verifica è deterministica per tutti gli stati possibili

Lost è un linguaggio 2D in cui la posizione iniziale e la direzione sono completamente casuali. Ciò significa che ci deve essere un sacco di controllo degli errori in ogni fase per assicurarsi di avere il puntatore di istruzioni corretto, e non è uno che ha appena vagato in modo casuale.

Spiegazione:

Tutte le /s sulla riga inferiore sono lì per assicurarsi che tutti i puntatori che si generano in direzione verticale o sulla riga inferiore vengano incanalati nella direzione giusta. Da lì, finiscono in molti posti diversi, ma tutti finiscono per entrare nel

 ^%?>
 ////

Che cancella tutti i numeri diversi da zero nello stack. Il ([after che cancella anche eventuali 0 in più.

Nel mezzo del clear, colpisce il %, che disattiva la 'sicurezza', che consente al programma di terminare quando colpisce il @(senza questo, il programma potrebbe terminare immediatamente se un puntatore è iniziato sul @).

Da lì esegue un quine in linguaggio 2D piuttosto semplice, avvolgendo una stringa letterale ( ") attorno alla prima riga, spingendo un "carattere duplicando uno spazio ( :2+) e quindi una nuova riga ( 52*). Per la seconda riga, crea un /carattere ( 95*2+) e lo duplica un mazzo ( >::1?:[:[[[[), prima di terminare alla fine @e stampare la pila implicitamente. Lo scopo ?1è di impedire al processo di creare troppi 0 se il puntatore entra presto, risparmiando di doverli cancellare in seguito.

Ho salvato 20 byte qui rendendo l'ultima riga dello stesso carattere, il che significa che potrei passare direttamente dal processo di duping alla fine @.

Spiegazione sul processo di duping:

[è un personaggio noto come "Porta". Se il puntatore colpisce il lato piatto di a [o a ], si riflette, altrimenti lo attraversa. Ogni volta che il puntatore interagisce con una porta, passa al tipo opposto. Usando questa conoscenza possiamo costruire una semplice formula per quante volte un'istruzione verrà eseguita in un >:[blocco.

Aggiungi la quantità iniziale di istruzioni. Per ognuno [, aggiungi 2 volte la quantità di istruzioni a sinistra. Per l'esempio >::::[:[[[, iniziamo con 5 come importo iniziale. La prima porta ha 4 istruzioni dupe, quindi aggiungiamo 4 * 2 = 8 a 5 per ottenere 13. Le altre tre porte hanno 5 duplicati alla loro sinistra, quindi aggiungiamo 3 * (5 * 2) = 30 a 13 per ottenere 43 istruzioni dupe eseguite e 44 >s in pila. Lo stesso processo può essere applicato ad altre istruzioni, come (spingere una grande quantità di oggetti dalla pila all'ambito, o come usato qui, per cancellare gli oggetti dalla pila.

Un trucco che ho usato qui per evitare di duplicare troppi 0 è il 1?. Se il personaggio è 0, ?non salta 1, il che significa che duplica 1 per il resto del duplicato. Questo rende molto più semplice cancellare lo stack in seguito.


25

Questi sono i due quines Ruby più brevi di SO :

_="_=%p;puts _%%_";puts _%_

e

puts <<2*2,2
puts <<2*2,2
2

Non chiedermi come funziona il secondo ...


8
Il secondo usa heredoc, <<2avvia una stringa nella riga successiva e *2ripete la stringa
Ming-Tang,

Perché hai bisogno del 2?
Calcolatrice

1
@CalculatorFeline È il terminatore della stringa heredoc (che deve apparire sulla propria riga). In realtà non deve essere un 2 però: tio.run/##KypNqvz/v6C0pFjBxsZAy0jHgAuFY8D1/z8A
Martin Ender

25

Fissione , 6 byte

Sembra che questo sia ora il più breve "corretto" tra queste risposte.

'!+OR"

Spiegazione

Il flusso di controllo inizia Rcon un singolo (1,0)atomo a destra . Colpisce "alternando la modalità di stampa e poi si avvolge attorno alla linea, stampando '!+ORprima di colpire di "nuovo lo stesso ed uscire dalla modalità di stampa.

Questo lascia lo "stesso da stampare. Il modo più breve è '"O(dove '"imposta la massa dell'atomo sul codice carattere di "e Ostampa il personaggio e distrugge l'atomo), ma se lo facessimo "interferirebbe con la modalità di stampa. Quindi invece impostiamo il valore dell'atomo su '!(uno in meno di "), quindi incrementiamo con +e quindi stampiamo il risultato con O.

alternative

Ecco un paio di alternative, che sono più lunghe, ma forse le loro tecniche ispirano qualcuno a trovare una versione più breve utilizzandole (o forse saranno più utili in alcune quine generalizzate).

8 byte usando Jump

' |R@JO"

Ancora una volta, il codice inizia alle R. Gli @scambi di massa ed energia da dare (0,1). Quindi l' Jatomo fa saltare la Oscala sul rettangolo ". Quindi, come prima, tutti tranne i "vengono stampati in modalità stringa. Successivamente, l'atomo colpisce |per invertire la sua direzione, quindi passa attraverso la '"Ostampa ". Lo spazio è un po 'fastidioso, ma sembra necessario, perché altrimenti 'renderebbe l'atomo trattato |come un personaggio anziché come uno specchio.

8 byte usando due atomi

"'L;R@JO

Questo ha due atomi, che iniziano da sinistra e da Ldestra R. L'atomo di sinistra ottiene il suo valore impostato dal '"quale viene quindi immediatamente stampato con O(e l'atomo distrutto). Per l'atomo di destra, scambiamo di nuovo massa ed energia, saltiamo sopra Oper stampare il resto del codice in modalità di stampa. Successivamente il suo valore viene impostato da 'Lma questo non importa perché l'atomo viene quindi scartato ;.


Tecnicamente non valido a causa della mancanza di codice / separazione dei dati nella fonte.
Calcolatrice

4
@CalculatorFeline '!+codifica ".
Martin Ender,

Non ho familiarità con Fission, ma |R@JO"'funzionerebbe o avresti ancora bisogno di quello spazio dopo il '?
MildlyMilquetoast

1
@MistahFiggins Penso di sì, ma soprattutto devi stampare il 'primo.
Martin Ender,

24

Cross-browser JavaScript (41 caratteri)

Funziona nei primi 5 browser Web (IE> = 8, Mozilla Firefox, Google Chrome, Safari, Opera). Inseriscilo nella console dello sviluppatore in uno di questi:

eval(I="'eval(I='+JSON.stringify(I)+')'")

Non è "imbroglio" - a differenza del quine a byte singolo di Chris Jester-Young, in quanto potrebbe essere facilmente modificato per utilizzare la alert()funzione (che costa 14 caratteri):

alert(eval(I="'alert(eval(I='+JSON.stringify(I)+'))'"))

O convertito in un bookmarklet (che costa 22 caratteri):

javascript:eval(I="'javascript:eval(I='+JSON.stringify(I)+')'")

24

C, 64 60 byte

main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Finora, questo è il C quine più breve conosciuto. C'è una taglia estesa se ne trovi una più corta.

Funziona in GCC , Clang e TCC in un ambiente POSIX . Richiama una quantità eccessiva di comportamento indefinito con tutti loro.

Solo per divertimento, ecco un repository che contiene tutte le C quine che conosco. Sentiti libero di fork / PR se ne trovi o ne scrivi uno diverso che aggiunge qualcosa di nuovo e creativo a quelli esistenti.

Si noti che funziona solo in un ambiente ASCII . Questo funziona per EBCDIC , ma richiede ancora POSIX . Buona fortuna a trovare comunque un ambiente POSIX / EBCDIC: P


Come funziona:

  1. main(s)abusa maindegli argomenti, dichiarando una variabile praticamente non tipizzata s. (Nota che in srealtà non è tipizzato, ma poiché i compilatori elencati lo lanciano automaticamente se necessario, potrebbe anche essere *.)
  2. printf(s="..."imposta sla stringa fornita e passa il primo argomento a printf.
  3. sè impostato su main(s){printf(s=%c%s%1$c,34,s);}.
  4. Il %cè impostato su ASCII 34, ". Questo rende possibile il quine. Ora sassomiglia a questo:
    main(s){printf(s="%s%1$c,34,s);}.
  5. Il valore %sè impostato su sse stesso, il che è possibile grazie al numero 2. Ora sassomiglia a questo:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}.
  6. Il %1$cè impostato su ASCII 34 ", printf's primo ** argomento. Ora sassomiglia a questo:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
    ... che sembra essere il codice sorgente originale.

* Esempio grazie al @Pavel
** primo argomento dopo l'identificatore di formato - in questo caso, s. È impossibile fare riferimento all'identificatore di formato.


Penso che sia impossibile che questo si accorcia con lo stesso approccio. Se lo printfspecificatore di formato fosse accessibile tramite $, questo funzionerebbe per 52 byte:

main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}

Anche se certamente non dovrebbe essere considerato in competizione, il vincitore del "Peggior abuso delle regole" dell'International Obfuscated C Code Contest del 1994, 1994_smr.c , è decisamente più breve.
Ray,

@Ray Non è permesso. Non è un vero e proprio quine da nessuna definizione. Le regole di quiete furono modificate a causa di quel programma: P
MD XF

Sono completamente d'accordo, ma è un trucco abbastanza interessante che vale la pena menzionare ogni volta che qualcuno menziona una quina più piccola conosciuta, anche se solo per motivi storici.
Ray,

4
sè di tipo int, non una "variabile non tipizzata".
febbraio

2
Tutti questi compilatori apparentemente consentono la conversione implicita di un puntatore a un int. s=3ovviamente non funzionerebbe perché devi passare la stringa due volte a printf.
febbraio

24

Java, 528 byte:

Una soluzione Java con un approccio originale:

import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp",36);int i=0;for(byte c:b.toByteArray()){if(++i==92)System.out.print(b.toString(36));System.out.print((char)c);}}}

in forma leggibile:

import java.math.*;
class a
{
    public static void main (String [] a)
    {
        BigInteger b=new BigInteger ("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp", 36); 
        int i=0; 
        for (byte c:b.toByteArray ())
        {
            if (++i==92) 
                System.out.print (b.toString (36)); 
            System.out.print ((char) c);
        }
    }
}

Come funziona?
Loovjo,

1
@Loovjo: simile ad altre soluzioni che tagliano il codice in due parti e inserisce l'intera stringa che ripropone il codice all'interno, ma l'intero codice non è solo una stringa ma codificato come il numero lungo nella base 36 (26 caratteri alfabetici + 10 cifre).
utente sconosciuto

1
Questo potrebbe essere abbreviato se lo metti if(++i==92),
tuskiomi

2
@tuskiomi: Grazie, abbreviato per due personaggi
utente sconosciuto il

1
@userunknown In realtà, a* poiché l'array non esce in Java, questo è C. Alcune altre parti per il golfimport 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);}} dove abcsarebbe il numero magico appena calcolato String. In java 8+ è anche possibile cambiare class a{public static void mainin interface a{static void main, e in Java 10+ è anche possibile cambiare import java.math.*;e BigInteger b=new BigInteger(in var b=new java.math.BigInteger(.
Kevin Cruijssen,

23

Pollo , 7

chicken

No, questo non viene ripetuto direttamente :)


Dannazione, mi hai battuto :)
Taconut,

Non fa eco, è la stringa chicken!
Erik the Outgolfer,

Nessuna separazione di codice / dati e quindi non valida.
Calcolatrice

10
@CalculatorFeline Hai letto le regole?
Timtech,

1
@JoKing Non penso che ciò non sia valido, perché le regole della sfida proibiscono solo le quine di lunghezza zero e cheat (leggendo il tuo file sorgente). L'unica cosa che proibisce le quine improprie è una scappatoia standard - tranne le scappatoie standard non sono generalmente considerate applicabili alle risposte che le precedono.
pepery

23

Retina , 20 14 9 7 byte

Prima di iniziare, vorrei menzionare la banale soluzione di un file che contiene un singolo 0. In tal caso, Retina proverà a contare le 0s nell'input vuoto, il cui risultato è anche 0. Non lo considero un vero quine.

Quindi eccone uno corretto:

>\`
>\`

Provalo online!

In alternativa, potremmo usare ; invece di >.

Spiegazione

Il programma consiste in una singola sostituzione che stampiamo due volte.

Nella prima riga, il ` separa la configurazione da regex, quindi regex è vuoto. Pertanto la stringa vuota (ovvero l'input inesistente) viene sostituita alla seconda riga, alla lettera.

Per stampare il risultato due volte, lo avvolgiamo in due fasi di output. Quello interno, \stampa il risultato con un avanzamento riga finale e quello esterno,> , lo stampa senza uno.

Se hai un po 'di familiarità con Retina, potresti chiederti cosa è successo all'output implicito di Retina. L'output implicito di Retina funziona avvolgendo la fase finale di un programma in una fase di output. Tuttavia, Retina non lo fa, se lo stadio finale è già uno stadio di uscita. La ragione di ciò è che in un normale programma è più utile essere in grado di sostituire lo stadio di uscita implicito con uno speciale simile \o ;per un singolo byte (invece di dover sbarazzarsi di quello implicito anche con il .flag). Sfortunatamente, questo comportamento finisce per costarci due byte per il quine.


20

Javascript (36 caratteri)

(function a(){alert("("+a+")()")})()

Questo è, AFAICT, il quine javascript più breve pubblicato finora.


1
Quello ... è impressionante. Dovresti spiegare come funziona per me 8- |
TehShrike,

3
@TehShrike Suggerimento: puoi visualizzare il contenuto di una funzione legandolo a una stringa. Ad esempio, se si dispone di una funzione a, è possibile accedere al suo contenuto chiamando a.toString.
Peter Olson,

7
Per essere pedanti, tuttavia, questo è solo un quine se l'implementazione JavaScript restringe la funzione aesattamente nello stesso modo in cui è stata scritta sopra. Tuttavia, è probabile che l' output di questo codice sia un quine su qualsiasi implementazione JavaScript.
Ilmari Karonen,

1
Ecco lo stesso Quine, 1 byte più breve: !function a(){alert("!"+a+"()")}().
Ismael Miguel,

1
(a=()=>alert(($ {a})))()
Dennis C,

19

GolfScript, 8 byte

Ho sempre pensato che il quine GolfScript (vero) più breve fosse 9 byte:

{'.~'}.~

Dove è necessario un avanzamento di riga finale perché GolfScript stampa un avanzamento di riga finale per impostazione predefinita.

Ma ho appena trovato un quine a 8 byte, che funziona esattamente attorno a quella limitazione dell'alimentazione di linea:

":n`":n`

Provalo online!

Quindi il problema è che GolfScript non stampa un avanzamento riga finale, ma stampa il contenuto di nalla fine del programma. È solo che ncontiene un avanzamento riga per cominciare. Quindi l'idea è di sostituirla con la stringa ":n`"e quindi di stringerla, in modo tale che la copia nello stack venga stampata con virgolette e copia memorizzata inn stampe senza.

Come sottolineato da Thomas Kwa, il quine CJam a 7 byte può anche essere adattato a una soluzione a 8 byte:

".p"
.p

Ancora una volta, abbiamo bisogno dell'alimentazione di linea finale.


6
Golfscript è strano.
Calcolatrice

19

Labyrinth , 124 110 53 byte

Grazie a Sp3000 per il golf off 9 byte, che mi ha permesso di golf altri 7.

44660535853919556129637653276602333!
1
:_98
/8 %
@9_.

Provalo online!

Spiegazione

Labyrinth 101:

  • Labyrinth è un linguaggio 2D basato su stack. Lo stack è senza fondo e pieno di zeri, quindi spuntare da uno stack vuoto non è un errore.
  • L'esecuzione inizia dal primo carattere valido (qui in alto a sinistra). Ad ogni giunzione, dove ci sono due o più possibili percorsi che il puntatore dell'istruzione (IP) deve prendere, la parte superiore dello stack viene controllata per determinare dove andare dopo. Il negativo è girare a sinistra, zero è andare avanti e il positivo è girare a destra.
  • Le cifre nel codice sorgente non inviano il numero corrispondente, ma fanno apparire la parte superiore dello stack e spingono n*10 + <digit>. Ciò consente di creare facilmente grandi numeri. Per iniziare un nuovo numero, utilizzare _, che spinge zero.
  • " sono vietati.

Innanzitutto, spiegherò una versione leggermente più semplice che è un byte più lunga, ma un po 'meno magica:

395852936437949826992796242020587432!
"
:_96
/6 %
@9_.

Provalo online!

L'idea principale è quella di codificare il corpo principale della fonte in un singolo numero, usando una base di grandi dimensioni. Questo numero può quindi essere facilmente stampato prima di essere decodificato per stampare il resto del codice sorgente. La decodifica è semplicemente l'applicazione ripetuta di divmod base, dove stampare mode continuare a lavorare condiv fino al suo zero.

Evitando {}, il codice del carattere più alto di cui avremo bisogno è _(95) in modo tale che la base 96 sia sufficiente (mantenendo la base bassa, il numero all'inizio è più breve). Quindi quello che vogliamo codificare è questo:

!
"
:_96
/6 %
@9_.

Trasformando quei caratteri nei loro punti di codice e trattando il risultato come un numero base-96 (con la cifra meno significativa corrispondente a !e la più significativa a ., perché è l'ordine in cui smonteremo il numero), otteniamo

234785020242697299628949734639258593

Ora il codice inizia con un trucco piuttosto interessante (se così posso dire) che ci consente di ristampare la codifica e conservare un'altra copia per la decodifica con un sovraccarico molto piccolo: inseriamo il numero nel codice al contrario. Ho calcolato il risultato con questo script CJam Quindi passiamo al codice reale. Ecco l'inizio:

395852936437949826992796242020587432!
"

L'IP inizia nell'angolo in alto a sinistra, andando verso est. Mentre scorre su quelle cifre, crea semplicemente quel numero in cima allo stack. Il numero stesso è del tutto privo di significato, perché è il contrario di ciò che vogliamo. Quando l'IP colpisce il! , viene visualizzato questo numero dallo stack e lo stampa. Questo è tutto ciò che serve per riprodurre la codifica nell'output.

Ma ora l'IP ha raggiunto un vicolo cieco. Ciò significa che si gira e ora si sposta indietro verso ovest (senza eseguire di !nuovo). Questa volta, convenientemente, l'IP legge il numero da dietro in avanti, in modo che ora il numero in cima alla pila fa codificare il resto della fonte.

Quando l'IP ora colpisce di nuovo l'angolo in alto a sinistra, questo non è un vicolo cieco perché l'IP può girare a sinistra, quindi lo fa e ora si sposta verso sud. Il "è un no-op, che abbiamo bisogno qui per separare il numero dal ciclo principale del codice. A proposito:

...
"
:_96
/6 %
@9_.

Finché la parte superiore dello stack non è ancora zero, l'IP eseguirà questo codice piuttosto denso nel seguente ciclo:

"
>>>v
^< v
 ^<<

O disposti in modo lineare:

:_96%._96/

La ragione per cui prende quelle svolte è a causa della semantica del flusso di controllo di Labyrinth. Quando ci sono almeno tre vicini alla cella corrente, l'IP girerà a sinistra su un valore di stack negativo, proseguirà su uno zero e gira a destra su un valore di stack positivo. Se la direzione scelta non è possibile perché c'è un muro, l'IP prenderà invece la direzione opposta (motivo per cui ci sono due giri a sinistra nel codice anche se la parte superiore dello stack non è mai negativa).

Il codice del loop stesso è in realtà piuttosto semplice (comprimendolo così strettamente non è ed è il contributo principale di Sp3000):

:    # Duplicate the remaining encoding number N.
_96  # Push 96, the base.
%.   # Take modulo and print as a character.
_96  # Push 96 again.
/    # Divide N by 96 to move to the next digit.

Una volta raggiunto lo Nzero, il flusso di controllo cambia. Ora l'IP vorrebbe spostarsi subito dopo /(cioè ad ovest), ma lì c'è un muro. Quindi invece se gira (est), esegue di 6nuovo il. Ciò rende la parte superiore dello stack positiva, quindi l'IP gira a destra (sud) ed esegue il file 9. La parte superiore dello stack è ora 69, ma tutto ciò che ci interessa è che sia positivo. L'IP prende un'altra svolta a destra (ovest) e si sposta sulla @quale termina il codice.

Tutto sommato, in realtà piuttosto semplice.

Bene, ora come possiamo eliminare quel byte aggiuntivo. Chiaramente, quella no-op sembra dispendiosa, ma abbiamo bisogno di quella riga aggiuntiva: se il loop fosse adiacente al numero, l'IP si muoverebbe già lì immediatamente invece di attraversare l'intero numero. Quindi possiamo fare qualcosa di utile con quel no-op.

Bene, in linea di principio possiamo usarlo per aggiungere l'ultima cifra alla codifica. La codifica non ha davvero bisogno di essere tutto sulla prima riga ... !assicura solo che qualunque cosa sia lì venga stampata lì.

C'è un problema però, non possiamo semplicemente fare questo:

95852936437949826992796242020587432!
3
:_96
/6 %
@9_.

Il problema è che ora abbiamo cambiato "in a 3, che cambia anche il numero effettivo che vogliamo avere. E abbastanza sicuro che quel numero non finisce 3. Dal momento che il numero è completamente determinato dal codice a partire da !non possiamo fare molto al riguardo.

Ma forse possiamo scegliere un'altra cifra? Non ci interessa davvero se c'è un punto 3in quel punto finché finiamo con un numero che codifica correttamente la fonte. Bene, sfortunatamente, nessuna delle 10 cifre produce una codifica la cui cifra meno significativa corrisponde a quella scelta. Fortunatamente, nel resto del codice è presente un margine di manovra tale che possiamo provare qualche altra codifica senza aumentare il conteggio dei byte. Ho trovato tre opzioni:

  1. Possiamo cambiare @in /. In tal caso, possiamo usare qualsiasi cifra da 1357e ottenere una codifica corrispondente. Tuttavia, ciò significherebbe che il programma termina con un errore, che è consentito ma non sembra molto pulito.
  2. Gli spazi non sono gli unici personaggi "a parete". Ogni personaggio inutilizzato è, in particolare tutte le lettere. Se usiamo una lettera maiuscola, non abbiamo nemmeno bisogno di aumentare la base per adattarla (dal momento che quei punti di codice sono sotto _). 26 scelte offrono molte possibilità. Ad esempio per Aqualsiasi cifra dispari funziona. Questo è un po 'più bello, ma non sembra ancora così elegante, dal momento che non avresti mai usato una lettera lì in codice reale.
  3. Possiamo usare una base maggiore. Finché non aumentiamo in modo significativo la base, il numero di cifre decimali nella codifica rimarrà lo stesso (in particolare, qualsiasi base fino a 104 va bene, anche se basi oltre 99 richiederebbero effettivamente caratteri aggiuntivi nel codice stesso). Fortunatamente, la base 98 offre un'unica soluzione di corrispondenza: quando usiamo la cifra 1, termina anche la codifica 1. Questa è l'unica soluzione tra le basi 96, 97, 98, 99, quindi è davvero molto fortunata. Ed è così che finiamo con il codice nella parte superiore di questa risposta.

19

Perso , 293 262 249 byte

>:2+52*:6*:(84*+75*):>:::::[[[[[[[:[(52*)>::::[[[[[[:[84*+@>%?!<((((((((((([[[[[[[[[[[[[[ "
\#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\

Provalo online!

Spiegazione

L'intero progetto è stato su e giù. Ho continuato a pensare che fosse impossibile e poi ho avuto un'idea folle che avrebbe potuto funzionare.

Perché un Lost Quine è così difficile?

Come forse saprai, Lost è un linguaggio di programmazione 2D in cui la posizione e la direzione di partenza sono completamente casuali. Questo rende difficile scrivere qualsiasi programma perso quanto scrivere codice indurito per radiazione. Devi considerare ogni possibile posizione e direzione.

Detto questo, ci sono alcuni modi standard per fare le cose. Ad esempio, ecco il modo standard di stampare una stringa.

>%?"Stringv"(@
^<<<<<<<<<<<<<

Questo ha un flusso di raccolta nella parte inferiore che afferra la maggior parte degli ips e li tira nella posizione iniziale. Quando raggiungono la posizione iniziale (in alto a sinistra), li disinfettiamo con un anello eliminando tutti i valori dallo stack, quindi giriamo la sicurezza di spingere la stringa ed uscire. (la sicurezza è un concetto unico di Lost che ogni programma deve raggiungere %prima di uscire, questo impedisce la possibilità che il programma termini all'avvio). Ora la mia idea sarebbe quella di estendere questo modulo in un quine a tutti gli effetti.

La prima cosa da fare era rielaborare un po 'il loop, il loop esistente era specifico del formato String.

>%?!<"Stringv"(@
^<<<<<<<<<<<<<<<
^<<<<<<<<<<<<<<<

Dobbiamo aggiungere un secondo flusso per evitare la possibilità di !saltare sopra il flusso e creare un ciclo.

Ora vogliamo mescolarlo con il formato Quine standard. Dato che Lost si basa molto su Klein, ho praticamente rubato il Klien Quine per Martin Ender .

:2+@>%?!< "
<<<<^<<<<<<
<<<<^<<<<<<

Questo stampa abbastanza convenientemente la prima riga del quine. Ora tutto ciò che dobbiamo fare è codificare in streaming i flussi. Bene, questo è più facile a dirsi che a farsi. Ho provato circa quattro diversi metodi per farlo. Descriverò solo quello che ha funzionato.

L'idea qui è di usare le porte per ottenere il numero desiderato di frecce. Una porta è un tipo speciale di specchio che cambia ogni volta che viene colpito. [riflette ips provenienti da sinistra e ]da destra. Quando vengono colpiti da un IP da uno di questi lati, l'orientamento dell'interruttore. Possiamo realizzare una linea di queste porte e un riflettore statico per eseguire ripetutamente un'operazione.

>:[[[

Si esibirà :tre volte. In questo modo se spingiamo prima uno <nello stack possiamo farne molti con meno byte. Ne facciamo 2, uno per ogni riga, e tra di essi stabiliamo una nuova riga, tuttavia la seconda deve solo andare fino a quando non copre quella per !cui l' abbiamo aggiunta, qualsiasi altra cosa può essere lasciata vuota salvandoci qualche byte. Ok ora dobbiamo aggiungere le frecce verticali ai nostri flussi. È qui che entra in gioco l'ottimizzazione dei tasti. Invece di reindirizzare tutti gli ips all '"avvio" del programma, li reindirizzeremo invece all'estrema sinistra, perché sappiamo già che gli ips iniziano all'estrema sinistra devonofunziona (o almeno funzionerà nella versione finale) possiamo anche reindirizzare gli altri ips. Questo non solo lo rende più economico in byte, penso che questa ottimizzazione sia ciò che rende possibile il quine.

Tuttavia ci sono ancora alcuni problemi, il più importante dei quali è l'ip che inizia dopo che >è stato spinto ma prima di iniziare a fare copie di esso. Tali ips entreranno nella fotocopiatrice e faranno un mucchio di copie di 0. Questo è un male perché il nostro meccanismo di eliminazione dello stack utilizza gli zeri per determinare il fondo dello stack, lasciando un intero gruppo di zeri in basso. Dobbiamo aggiungere un metodo di risanamento dello stack più forte. Dal momento che non esiste un vero modo per dire se la pila è vuota, dovremo semplicemente tentare di distruggere il maggior numero possibile di oggetti nella pila. Qui useremo ancora una volta il metodo della porta descritto in precedenza. Aggiungeremo ((((((((((([[[[[[[[[[[[[[alla fine della prima riga subito dopo il sanitizor per sbarazzarci degli zeri.

Ora c'è un altro problema, dal momento che abbiamo reindirizzato i nostri flussi verso l'ip in alto a sinistra a partire da %e spostando verso il basso avrà già disattivato la sicurezza e uscirà prematuramente. Quindi dobbiamo disattivare la sicurezza. Facciamo questo aggiungendo #a allo stream, in questo modo ips che fluiscono attraverso lo stream verranno disattivati, ma ips che sono già stati disinfettati non lo faranno. La #deve anche essere difficile codificato nella prima linea pure.

Ecco, spero che tu capisca come funziona ora.


: / così tanti errori di battitura e collegamenti mancanti
solo ASCII

17

, 1165 879 606 561 540 522 498 + 7 = 505 byte

Richiede il -cheatflag per consentire la definizione di alias.

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Provalo online!

Spiegazione

Ci sono due parti in questo (come con la maggior parte delle quines). I dati:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

E il decodificatore:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

I dati sono semplicemente una codifica binaria del decodificatore (o meglio il suo contrario). Ognuno 0inizia un nuovo personaggio e la 1s e2 s sono rispettivamente 0- e 1--bit.

Si noti che 0è un comando Yup standard che spinge uno zero, mentre 1e 2non sono definiti in questo punto. Tuttavia, assegniamo l'intera parte di dati al comando in %modo che il file1 e 2possa rimanere indefinito fino a quando non %viene effettivamente utilizzato.

Successivamente, definiamo alcuni altri comandi:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

<decrementa la parte superiore della pila, la >incrementa. 1(in qualche modo non intuitivo) raddoppia la parte superiore della pila.2lo raddoppia e poi lo incrementa. Grazie a queste definizioni, qualcosa del genere 0221111lascerà effettivamente uno 48 (110000 in binario) nello stack.

I restanti 32 byte eseguono la decodifica effettiva in due parti. Per prima cosa dobbiamo ricostruire la stringa di dati.

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

E infine, inviamo nuovamente i dati e stampiamo ogni valore come carattere:

%{@}

Per riferimento futuro, ecco uno script CJam per codificare i dati.


17

Fueue , 423 byte

Fueue è un esolang basato sulla coda in cui il programma in esecuzione è la coda.

)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Provalo online!

Come funziona

Questa spiegazione può o non può essere sfuggita di mano. D'altra parte non so come spiegarlo molto più breve in un modo che spero che la gente possa seguire.

Fueue cheat sheet

Vedi l' articolo wiki di esolang per i dettagli, incluse le poche funzioni non utilizzate in questo programma.

  • Il programma iniziale è lo stato iniziale della coda, che può contenere i seguenti elementi:

    • Letterali interi (solo non negativi nella fonte, ma quelli negativi possono essere calcolati), eseguendoli stampa un carattere.
    • Blocchi nidificati delimitati da parentesi quadre, inerti (conservati intatti a meno che alcune funzioni non agiscano su di essi).
    • Funzioni, i loro argomenti sono gli elementi che li seguono immediatamente nella coda:
      • +*/-%: aritmetica intera ( -è unaria, %negazione logica). Argomenti numerici inerti se non indicati.
      • ()<: mette l'elemento tra parentesi, rimuove le parentesi dal blocco, aggiunge l'elemento finale al blocco. Gli ultimi due sono inerti a meno che non siano seguiti da un blocco.
      • ~:: swap, duplicato.
      • $: copia (richiede il numero + elemento). Inerte prima di non numero.
      • H: programma di arresto.

    Nota che, mentre []annidate, ()non farlo - queste ultime sono semplicemente funzioni separate.

Sintassi della traccia di esecuzione

Lo spazio bianco è facoltativo in Fueue, tranne tra i numeri. Nelle seguenti tracce di esecuzione verrà utilizzato per suggerire la struttura del programma, in particolare:

  • Quando viene eseguita una funzione, essa e i suoi argomenti saranno messi in risalto dagli spazi circostanti con spazi. Se alcuni degli argomenti sono complicati, potrebbe esserci anche uno spazio tra loro.
  • Molte tracce di esecuzione sono divise in un "BLOB di ritardo" a sinistra, separato da una parte a destra che esegue la sostanziale manipolazione dei dati. Vedi la prossima sezione.

Le parentesi graffe {}(non utilizzate in Fueue) vengono utilizzate nelle tracce per rappresentare il risultato intero delle espressioni matematiche. Questo include numeri negativi, poiché Fueue ha solo valori letterali non negativi - -è la funzione di negazione.

Vari nomi metavariabili e ...vengono utilizzati per indicare valori e abbreviazioni.

Ritardare le tattiche

Intuitivamente, l'esecuzione esegue un ciclo attorno alla coda, modificando parzialmente ciò che passa. I risultati di una funzione non possono essere nuovamente attivati ​​fino al ciclo successivo. Diverse parti del programma si evolvono efficacemente in parallelo purché non interagiscano.

Di conseguenza, gran parte del codice è dedicato alla sincronizzazione, in particolare al ritardo nell'esecuzione di parti del programma fino al momento giusto. Ci sono molte opzioni per giocare a golf, che tende a trasformare quelle parti in macchie illeggibili che possono essere comprese solo tracciando il loro ciclo di esecuzione ciclo per ciclo.

Queste tattiche non saranno sempre menzionate individualmente nel seguito:

  • )[A]ritardi Aper un ciclo. (Probabilmente il metodo più semplice e più leggibile.)
  • ~efscambia gli elementi ee fciò ritarda anche la loro esecuzione. (Probabilmente il meno leggibile, ma spesso il più breve per ritardi minori.)
  • $1eritarda un singolo elemento e.
  • -e %sono utili per ritardare i numeri (quest'ultimo per 0e 1.)
  • Quando si ritardano più elementi uguali di seguito, :oppure$ possono essere utilizzati per crearli da un singolo.
  • (nè racchiuso ntra parentesi, che possono essere rimosse in seguito a piacimento. Ciò è particolarmente vitale per i calcoli numerici, poiché i numeri sono troppo instabili per essere copiati senza prima metterli in un blocco.

Struttura generale

Il resto della spiegazione è diviso in sette parti, ciascuna per una sezione del programma in esecuzione. I cicli più grandi dopo i quali la maggior parte di essi si ripetono saranno chiamati "iterazioni" per distinguerli dai "cicli" dei singoli passaggi attraverso l'intera coda.

Ecco come si divide il programma iniziale tra loro:

A:  )$$4255%%1(~
B:  ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:  
D:  (H-
E:  
F:  
G:  ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Il grande numero alla fine del programma codifica il resto al contrario, due cifre per carattere, con 30 sottratte da ciascun valore ASCII (quindi ad esempio 10codifica un( .)

A un livello superiore puoi pensare ai dati di questo programma (a partire dal bignum) come che scorre da destra a sinistra, ma controlla il flusso da sinistra a destra. Tuttavia, a un livello inferiore, Fueue confonde continuamente la distinzione tra codice e dati.

  • La sezione G decodifica il bignum in cifre ASCII (ad es. Cifra 0come numero intero 48), suddividendo prima le cifre meno significative. Produce una cifra ogni 15 cicli.
  • La sezione F contiene i valori ASCII della cifra prodotta (ciascuno all'interno di un blocco) fino a quando la sezione E li può consumare.
  • La sezione E gestisce le cifre prodotte due alla volta, accoppiandole in blocchi del modulo [x[y]], stampando anche il carattere codificato di ciascuna coppia.
  • La sezione D è costituita da un blocco nidificato in profondità costruito gradualmente dai [x[y]]blocchi in modo tale che una volta che contenga tutte le cifre, possa essere eseguito per stamparle tutte, quindi arrestare l'intero programma.
  • La sezione C gestisce la costruzione della sezione D e ricrea anche la sezione E.
  • La sezione B ricrea la sezione C e se stessa ogni 30 cicli.
  • La sezione A esegue il conto alla rovescia dei cicli fino all'ultima iterazione delle altre sezioni. Quindi interrompe la sezione B ed esegue la sezione D.

Sezione a

La sezione A gestisce la pianificazione della fine del programma. Sono necessari 4258 cicli per ridurre a una singola funzione di scambio ~, che quindi effettua una regolazione alla sezione B che interrompe il suo ciclo principale e inizia invece a eseguire la sezione D.

)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
  • Una $funzione crea 4255 copie di quanto segue %mentre racchiude (le ~parentesi quadre.
  • Ad ogni ciclo l'ultimo %viene utilizzato per alternare il seguente numero tra 0e 1.
  • Quando tutti gli %s sono esauriti, $1crea 1 copia del [~](effettivamente un NOP), e nel ciclo successivo )rimuove le parentesi.

Sezione B

La sezione B gestisce la rigenerazione e una nuova iterazione della sezione C ogni 30 cicli.

) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]            [BkB]
)$ $24%     %0  :<  [~:)~)]    ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1   < < [~:)~)] [BkB]   [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0      < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1         [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                    (1)
~:) ~)[BkB]                 [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB]                 ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]      (2)
) [BkB] [BkB]               $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
  • A :duplica il blocco grande seguente (una copia abbreviata come [BkB]), quindi )rimuove le parentesi dalla prima copia.
  • $$24%%0 imposta un conto alla rovescia simile a quello nella sezione A.
  • Mentre questo fa il conto alla rovescia, :<si trasforma in <<e ~scambia due dei blocchi, posizionando il codice per una nuova sezione C per ultima.
  • Le due <funzioni racchiudono i due blocchi finali nel primo: questo è ridondante nelle iterazioni normali, ma consentirà alla ~sezione A di fare il suo lavoro alla fine.
  • (1) Al termine del conto alla rovescia, )rimuove le parentesi esterne. Successivamente ~:)si trasforma ):e si ~)scambia )a all'inizio del codice della sezione C.
  • (2) La sezione B è ora tornata al suo ciclo iniziale, mentre a )sta per rimuovere le parentesi per iniziare a eseguire una nuova iterazione della sezione C.

Nell'iterazione finale, ~dalla sezione A appare al punto (1) sopra:

~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                  (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]              )

Gli ~swap del )tutto il blocco e nella sezione C, impedendo sezione B vengano eseguiti nuovamente.

Sezione C

La sezione C gestisce l'unione di nuove coppie di caratteri numerici nel blocco della sezione D e crea anche nuove iterazioni della sezione E.

Di seguito viene mostrata una tipica iterazione con xe che yrappresenta i codici ASCII delle cifre. Nella primissima iterazione, gli elementi "D" ed "E" in arrivo sono gli elementi iniziali [H]e -invece, poiché nessuna sezione precedente E è stata eseguita per produrre coppie di caratteri numerici.

C                                               D             E
$11~ )  ~<[[+$4--498+*-:~-10)):])<~]  [)))~]  < [)))~[...]]   [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~]  < [)))~] [)))~[...][x[y]]]
~~~ ~~~     )  ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~       ~ )   [)))~[....]]                                  [[+$4--498+*-:~-10)):])<~]
                                              ~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
                                                [)))~[....]]  ~[+$4--498+*-:~-10)):])<~
  • Questo utilizza un diverso metodo di sincronizzazione che ho scoperto per questa risposta. Quando si hanno diverse funzioni di scambio ~in una riga, la riga si riduce a circa 2/3 di ogni ciclo (perché uno ~scambia due successivi), ma occasionalmente con un resto di ~s che provoca il caos manipola attentamente ciò che segue.
  • $11~produce una tale riga. Il prossimo ~scambia a <attraverso il blocco seguente. Un altro <alla fine aggiunge un nuovo blocco di coppie di cifre (cifre xey come codici ASCII) nel blocco sezione D.
  • Il ciclo successivo, la ~riga ha un ~~resto, che sostituisce ~il seguente ). L'altro <aggiunge la sezione D a un [)))~]blocco.
  • Successivamente lo ~stesso swap scambia il blocco seguente con il nuovo codice della sezione E attraverso il blocco della sezione D. Quindi un nuovo avanzi ~scambia un )attraversamento, e infine l'ultimo ~~nella ~riga scambia uno di essi attraverso la sezione E proprio come )ha rimosso le sue parentesi.

Nell'iterazione finale, la sezione A ~ha scambiato una )sezione trasversale B e una sezione C. Tuttavia, la sezione C ha una durata così breve che è già scomparsa, e )finisce all'inizio della sezione D.

Sezione D

La sezione D gestisce la stampa del grande numero finale e l'arresto del programma. Durante la maggior parte dell'esecuzione del programma, è un blocco inerte che le sezioni B – G cooperano alla costruzione.

    (H -
    [H]-
    ⋮
    [)))~[H-]]                  After one iteration of section C
    ⋮
    [)))~[)))~[H-][49[49]]]]    Second iteration, after E has also run
    ⋮
)   [)))~[...]]     [49[48]]    Final printing starts as ) is swapped in
    ))) ~[...][49[48]]
    )) )[49[48]] [...]
    )) 49 [48][...]             Print first 1
    ) )[48] [...]
    ) 48 [...]                  Print 0
    )[...]                      Recurse to inner block
    ...
    ⋮
    )[H-]                       Innermost block reached
    H -                         Program halts
  • Nel primo ciclo del programma, a racchiude tra parentesi la (funzione di arresto H. A -seguito, verrà utilizzato come elemento fittizio per la prima iterazione anziché una coppia di cifre.
  • La prima coppia di cifre reali incorporata è [49[49]], corrispondente alla finale 11nel numero.
  • L'ultima coppia di cifre [49[48]](corrispondente 10all'inizio del numero) non è effettivamente incorporata nel blocco, ma questo non fa differenza in quanto )[A[B]]e )[A][B]sono equivalenti, entrambi si trasformano in A[B].

Dopo l'iterazione finale, lo )scambio dalla sezione B a destra arriva e il blocco della sezione D viene sbloccato. )))~L'all'inizio di ciascun sottoblocco fa in modo che tutte le parti siano eseguite nell'ordine corretto. Infine, il blocco più interno contiene un Harresto del programma.

Sezione E

La sezione E gestisce la combinazione di coppie di cifre ASCII prodotte dalla sezione G ed entrambe stampa il carattere codificato corrispondente e invia un blocco con la coppia combinata verso sinistra alle sezioni C e D.

Ancora una volta il seguente mostra una tipica iterazione con xe che yrappresenta i codici ASCII delle cifre.

E                                                   F
~ [+$4--498+*-:~-10)):] )              <  ~         [y] [x]
) [+$4--498+*-:~-10)):]                   < [x] [y]
+ $4-  - 498  +*- :~ -10 ) )              : [x[y]]
+---  -{-498} +*- ~~{-10} )       ) [x[y]]  [x[y]]
+--    - 498  +*   -{-10}       ~ ) x  [y]  [x[y]]
+-    -{-498} +               * 10 x  )[y]  [x[y]]
+      - 498                    + {10*x} y  [x[y]]
                         + {-498} {10*x+y}  [x[y]]
{10*x+y-498}  [x[y]]
[x[y]]
  • I blocchi di cifre in entrata vengono scambiati, quindi il blocco y viene aggiunto al blocco x e l'intero blocco di coppie viene copiato. Una copia rimarrà fino alla fine per le sezioni C e D.
  • L'altra copia viene nuovamente sbloccata, quindi viene applicata una sequenza di funzioni aritmetiche per calcolare 10*x+y-498il valore ASCII del carattere codificato. 498 = 10*48+48-30, 48s annulla la codifica ASCII di xe ymentre 30sposta la codifica da 00–99a 30–129, che include tutte le ASCII stampabili.
  • Il numero risultante viene quindi lasciato da eseguire, che stampa il suo carattere.

Sezione F

La sezione F è costituita da blocchi inerti contenenti codici ASCII di cifre. Per la maggior parte del programma in esecuzione ce ne saranno al massimo due qui, poiché la sezione E li consuma alla stessa velocità con cui G li produce. Tuttavia, nella fase di stampa finale alcune 0cifre ridondanti verranno raccolte qui.

[y] [x] ...

Sezione G

La sezione G gestisce la suddivisione del grande numero alla fine del programma, prima le cifre meno significative e l'invio di blocchi con i loro codici ASCII a sinistra verso le altre sezioni.

Poiché non ha alcun controllo di interruzione, continuerà effettivamente a produrre 0cifre quando il numero si è ridotto a 0, fino a quando la sezione D interrompe l'intero programma con la Hfunzione.

[BkG] abbrevia una copia del grande blocco di codice iniziale, che viene utilizzato per l'auto-replica per avviare nuove iterazioni.

Inizializzazione nei primi cicli:

) :~  : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
)  ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]     ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]       ~ : [10...11]  [BkG]

Tipica iterazione, Nindica il numero da dividere:

) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]        ~ : [N]  [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 )         : [N]  : [BkG]
)  ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]  +5 5     ) [N]  [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]               ~ 10 N  [N] [BkG] [BkG]
) ~:~  ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~]               / N 10  [N] [BkG] [BkG]
)  ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                 ( {N/10}  [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                    : [{N/10}]  [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 )           ~ ~ [{N/10}]  [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 )             ) [{N/10}]  ~ [{N/10}] [N]  [BkG] [BkG]
)  ~ * [):~[$1(+48]):~+]  -10            ~ ) {N/10}  [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+]               * {-10} {N/10}  ) [N]  [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~                 + {-10*(N/10)} N  [{N/10}] [BkG] [BkG]
)  ~ ~ [$1(+48]  )                 ~ ~ {N%10}  [{N/10}] [BkG] [BkG]
) [$1(+48]                 ~ ) {N%10}  ~ [{N/10}] [BkG]  [BkG]
$1(                     + 48 {N%10}    ) [BkG]  [{N/10}] [BkG]
                        ( {48+N%10}   BkG [{N/10}] [BkG]            New iteration starts
                        [{48+N%10}]   ....
  • La macchia di ritardo qui è particolarmente pelosa. Tuttavia, l'unico nuovo trucco di ritardo è usare +:5invece di --10ritardare 10due cicli. Purtroppo solo uno dei 10programmi in programma è stato aiutato da questo.
  • I blocchi [N]e [BkG]vengono duplicati, quindi una copia di Nviene divisa per 10.
  • [{N/10}]viene duplicato, quindi vengono utilizzate più funzioni aritmetiche per calcolare il codice ASCII dell'ultima cifra di Nas 48+((-10)*(N/10)+N). Il blocco con questo codice ASCII è lasciato per la sezione F.
  • L'altra copia di [{N/10}]viene scambiata tra i [BkG]blocchi per impostare l'inizio di una nuova iterazione.

Bonus quine (540 byte)

)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63

Provalo online!

Dato che non ero sicuro di quale metodo sarebbe stato il più breve, ho prima provato a codificare i caratteri come numeri a due cifre separati da (s. Il codice principale è un po 'più breve, ma la rappresentazione dei dati più grande del 50% lo compensa. Non tanto da golf quanto l'altro, come mi sono fermato quando ho capito che non l'avrebbe battuto. Ha un vantaggio: non richiede un'implementazione con supporto bignum.

La sua struttura complessiva è in qualche modo simile a quella principale. Manca la sezione G poiché la rappresentazione dei dati riempie direttamente la sezione F. Tuttavia, la sezione E deve eseguire un calcolo divmod simile per ricostruire le cifre dei numeri a due cifre.


1
Si dovrebbe golf la spiegazione XD
VFDan

1
)$n[)](è un byte più breve per il contatore del ritardo.
jimmy23013

15

Gelatina, 3 byte

”ṘṘ

Provalo online!

Verifica

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

Come funziona

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ

Quale versione dell'interprete utilizza questo? Quando lo collaudo, viene emesso in UTF-8 anche se l'input è nella tabella codici di Jelly (e il cambiamento nella codifica lo renderebbe non-a-quine).

1
La codifica dell'output dipende dalle impostazioni del tuo terminale: se è impostato su UTF-x, lo utilizza; se è impostato su qualsiasi altra cosa, utilizza la tabella codici di Jelly. Su Linux, LANG=en_USottiene proprio questo. tio.run/nexus/bash#@@/…
Dennis
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.