Écrivez un programme ou une fonction non vide qui, lorsqu'il est appelé, génère une seule valeur, 1 ou 0, et lorsqu'il est appelé plusieurs fois, les numéros de sortie produisent la représentation binaire du code source de votre programme (dans la même page de code à partir de laquelle votre code est compilé). / interprété).
Par exemple, si votre code source était abc
(en ASCII), les sorties seraient:
1st call: 0 // ASCII letter 'a'
2nd call: 1
3rd call: 1
4th call: 0
5th call: 0
6th call: 0
7th call: 0
8th call: 1
9th call: 0 // ASCII letter 'b'
10th call: 1
11th call: 1
12th call: 0
13th call: 0
14th call: 0
15th call: 1
16th call: 0
17th call: 0 // ASCII letter 'c'
18th call: 1
19th call: 1
20th call: 0
21st call: 0
22nd call: 0
23rd call: 1
24th call: 1
After the 24th call, the behaviour is undefined.
La représentation binaire de la source doit contenir au moins un bit 0 et un bit 1.
Au lieu de 1 et 0, vous pouvez générer deux valeurs cohérentes distinctes (telles que true
et false
).
Les programmes auto-modifiables qui produisent la représentation binaire de la source d'origine sont autorisés, à condition qu'ils ne lisent pas le code source pour savoir quoi imprimer ensuite.
Il s'agit de code-golf , donc la réponse la plus courte en octets l'emporte.
Bash , 105 octets
Remarque : assurez-vous que vous n'avez pas un fichier important appelé
f
dans le répertoire que vous testez.Si vous souhaitez tester cela, vous pouvez utiliser la commande suivante:
Ce qui devrait donner la même sortie
xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\n
.Explication
Ceci utilise l'
trap
astuce - appelertrap
à l'intérieur de l'trap
action imprime simplement cette ligne. Ensuite, cette sortie est canalisée versxxd
laquelle la convertit en binaire (malheureusementxxd -bp
ne fonctionne pas - donc la solution de contournement aveccut
&tr
):De cela, nous ne sommes intéressés que par un bit (disons
N
) avec lequel nous pouvons sélectionnercut -cN
.Pour savoir ce
N
que nous utilisons (rappelez-vous que c'est la partie qui doit être incrémentée après chaque appel), essayez simplement de définirx
le contenu du fichierf
et s'il n'existe pas, définissez-le sur 1:La dernière chose à faire est de mettre à jour le fichier
f
- en y écrivantx+1
:la source
TI-Basic (série TI-83),
592357309 octetsCe tableau est une référence possible pour la représentation binaire de la calculatrice du code source, bien que finalement je viens d'utiliser le débogueur de Virtual TI.
A titre de comparaison et / ou d'intérêt historique: les premiers quines écrits en TI-Basic .
Comment ça fonctionne
Str1
stocke le code source (maintenant en hexadécimal glorieux, économisant beaucoup d'espace sur la version binaire précédente), en laissant de côté les bits où le contenu deStr1
lui-même serait représenté.Nous partons du principe que le programme démarre sur une calculatrice dont la mémoire vient d' être effacé, donc
X
est0
. Chaque fois que nous parcourons le programme, nous progressonsX
.Habituellement, nous venons de comprendre le demi-octet dont nous essayons d'extraire un peu, de le lire
Str1
, de le convertir en hexadécimal en binaire et de l'imprimer. Si nous sommes sur la partie du code source qui est de stockerStr1
( ce qui est des deux tiers de la longueur totale du programme), puis nous avons d' abord passer à la partie de la chaîne de stockage correspondante31
,32
et ainsi de suite.la source
Java 8,
249241237234148 octetsDésolé d'avance pour les longues explications. :)
Essayez-le ici.
Explication:
Explication supplémentaire:
quine -part:
String s
contient le code source non formaté%s
est utilisé pour mettre cette chaîne en elle-même avecs.format(...)
%c
,%1$c
Et34
sont utilisés pour formater les guillemets doubles ("
)s.format(s,34,s)
met tout cela ensembleEssayez-le ici avec certaines parties supprimées / modifiées pour vérifier les sorties quine est son propre code source.
partie binaire :
-i/8
tronquera automatiquement sur la division entière, donc quandi
est -7 à 0, il deviendra0
; sii
est -15 à -8, il deviendra1
; etc.s.charAt(-i/8)
le caractère actuel du code source, huit fois l'un après l'autre. Essayez-le ici avec une version modifiée.--i&7
sera7,6,5,4,3,2,1,0,7,6,5,4,3,2,1,0,...
, où le premier7
est quandi=0
(qui devient le-1
premier à cause du--i
, et continuera à diminuer).s.charAt(-i/8)>>(--i&7)
produira des séquences en fonction des personnages. Quelques exemples ('A'
(65) à'E'
(69) sont):0,1,2,3,4,8,16,32,65,0,1,2,4,8,16,32,65,...
:;0,1,2,4,8,16,33,66,0,1,2,4,8,16,33,66,...
:;0,1,2,4,8,16,33,67,0,1,2,4,8,16,33,67,...
:;0,1,2,4,8,17,34,68,0,1,2,4,8,17,34,68,...
:;0,1,2,4,8,17,34,69,0,1,2,4,8,17,34,69,...
:;...&1
génère ensuite un0
si c'est un nombre pair, et1
si c'est un nombre impair, qui en combinaison avec les séquences ci-dessus génère le résultat correct.Ancien 233 octets réponse:
Essayez-le ici.
Explication:
Explication supplémentaire:
quine -part:
Même explication que ci-dessus, avec l'ajout de:
%%
est la forme échappée du signe modulo (%
)Essayez-le ici avec certaines parties supprimées / modifiées pour vérifier les sorties quine est son propre code source.
partie binaire :
i/8
tronquera automatiquement sur la division entière, donc quandi
est 0-7, il deviendra0
; sii
est 8-15, il deviendra1
; etc.s.charAt(i/8)
le caractère actuel du code source, huit fois l'un après l'autre. Essayez-le ici avec une version modifiée.255
est0xFF
ou11111111
(la valeur maximale pour un octet non signé)256
est0x100
ou100000000
.&
upcasts le caractère ASCII à un entier. À ce stade, c'est n'importe où entre0
et255
(00000000
à11111111
).Long.toString(...,2)
le convertit en représentation de chaîne binaire 9 bits+256
et.substring(1)
garantira qu'il y a des zéros non significatifs, et convertira le 9 bits en 8 bits.Essayez-le ici avec certaines parties supprimées / modifiées pour vérifier la totalité des octets.
la source
int i;v->{String s="int i;v->{String s=%c%s%1$c;return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}";return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}
Javascript ES6,
735852 octetsExplication
Répartition du code:
o=_=>
: définir une fonction.`o=${o}`
: construire une chaîne;o
est converti en chaîne, qui dans ce cas est le code source de la fonction..charCodeAt(
: récupère un caractère dans la chaîne comme son code de caractère ASCII.(o.n=1+o.n|0)/8
: sélectionnez un caractère. C'est également là que le compteur est incrémenté.)>>(7-o.n%8)
: décale le code de caractère résultant pour que le bit souhaité soit dans la bonne position.&1
: mettre tous les autres bits à 0.la source
o=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
o=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
'n'in top?++n:n=0
vous pouvez utiliser++n||(n=0)
ou++n?n:n=0
oun=++n||0
oun=1+n||0
qui utilisent tous la faussetéNaN
qui est produite par incrémentationundefined
o=_=>('o='+o).charCodeAt((o.n=1+o.n|0)/8)>>(~o.n&7)&1
q / kdb + , 45 octets
Solution:
Exemple:
Explication:
Je pense avoir compris le mémoire.
Configurez d'abord une variable globale
a
avec une valeur de départ de-1
. La fonctionf
construit la représentation binaire de la représentation sous forme de chaîne de la fonction (tout y compris le{}
) précédée de laa:-1;f:
jonque, et indexe dans cette liste binaire à l'index a (qui est incrémenté à chaque appel).la source
Python 2 , 164 octets
Essayez-le en ligne!
Explication
Commençons par une quine Python 2 standard.
Bon, eh bien, ça sort comme ça. Nous avons besoin de binaire!
D'accord, cela convertit simplement tout en binaire. Mais le titre dit "un bit à la fois". Nous avons besoin de quelque chose pour persister pendant plusieurs exécutions. Je sais, faisons-en une fonction!
Attendez, cela n'aide pas ... Hmm, comment pouvons-nous garder une trace de l'index du bit nécessaire pour être sorti? Ooh, ooh, ayons un entier pour garder une trace.
Um ... qui sort toujours le premier bit. Oh, nous devons incrémenter le tracker! Oh merde, Python n'autorise pas la modification des entiers comme arguments par défaut. Et les affectations ne sont pas des expressions en Python, vous ne pouvez donc pas le faire dans un lambda. Welp, c'est impossible en Python, affaire close.
... Enfin, pas tout à fait. Python ne permet listes comme arguments par défaut à modifier. (Et il mord tout le temps aux programmeurs Python.) Utilisons sa longueur!
Mais cela ne modifie toujours pas le tracker ... Nous pouvons y ajouter quelque chose pour augmenter sa longueur ... Mais comment? Ah, eh bien, nous avons
list.append
.lst.append(1)
est équivalent àlst += [1]
. Génial!Oups, cela saute le premier bit car la longueur du tracker est de 1 avant que le bit ne soit émis. Nous devons décrémenter la longueur où il est utilisé.
Ça y est, les amis! Jouez au golf et vous avez ma solution!
la source
Perl 5 , 59 octets
Essayez-le en ligne!
la source