Quine sort lui-même en binaire

10

Votre tâche, si vous souhaitez l'accepter, est d'écrire un programme qui génère son propre code source dans la représentation binaire UTF-8 .

Règles

  • La source doit avoir au moins 1 octet de long.

  • Votre programme ne doit pas accepter d'entrée (ou avoir une entrée vide non utilisée).

  • La sortie peut être dans n'importe quel format approprié.

  • La nouvelle ligne de fin facultative est autorisée.

  • Notez qu'un octet est de 8 bits, et la longueur de la représentation binaire UTF-8 est nécessairement un multiple de 8.

  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.

  • Les failles standard sont interdites.

Exemple

Disons que votre code source est Aä$$€h, sa représentation binaire UTF-8 correspondante est 010000011100001110100100001001000010010011100010100000101010110001101000.

Si je lance Aä$$€hla sortie doit être 010000011100001110100100001001000010010011100010100000101010110001101000.

A      --> 01000001
ä      --> 1100001110100100
$      --> 00100100
$      --> 00100100
€      --> 111000101000001010101100
h      --> 01101000
Aä$$€h --> 010000011100001110100100001001000010010011100010100000101010110001101000

Convertisseurs de chaînes en binaires UTF-8

mdahmoune
la source
1
Par "binaire", voulez-vous dire une représentation sous forme de chaîne des valeurs binaires, c'est-à-dire une chaîne composée uniquement de 1 et de 0?
1
@mdahmoune Maintenant, c'est déjà beaucoup mieux. La question reste de savoir comment représenter quelque chose comme UTF-8. Notez que la représentation Unicode est principalement basée sur l' apparence d'un personnage (seulement occasionnellement sur la signification sémantique). Que faire si aucun glyphe Unicode attribué ne ressemble à un caractère dans le code source? Unicode a également de nombreux sosies (homoglyphes). Comment décide-t-on lequel utiliser? Par exemple , Dyalog APL a une fonction ET qui peut être codé comme 01011110ou 0010011100100010en UTF-8 (ils ont l' air assez ressemblent: ^vs )
Adám
1
Meilleur exemple: 01111100et 0010001100100010encoder |et .
Adám
4
@ Adám Je pense qu'il serait juste de sortir n'importe quelle séquence binaire qui correspond à un symbole qui se compilera / s'exécutera dans une certaine implémentation d'un langage.
qwr
1
Et le code machine? (Le commodore C64 prend 28 octets en supposant que le code machine lui-même est la "source")
Martin Rosenau

Réponses:

7

V , 28 (ou 16?) Latin 1 octets (35 UTF-8 octets)

ñéÑ~"qpx!!xxd -b
ÎdW54|D
Íßó

Essayez-le en ligne!

Hexdump (en latin 1):

00000000: f1e9 d17e 2271 7078 2121 7878 6420 2d62  ...~"qpx!!xxd -b
00000010: 0ace 6457 3534 7c44 0acd dff3            ..dW54|D....

Sortie (représentation binaire du même code en UTF-8, pas en latin 1):

110000111011000111000011101010011100001110010001011111100010001001110001011100000111100000100001001000010111100001111000011001000010000000101101011000100000110111000011100011100110010001010111001101010011010001111100010001000000110111000011100011011100001110011111110000111011001100001010

Explication:

ñéÑ~"qpx            " Standard quine. Anything after this doesn't affect the
                    " program's 'quine-ness' unless it modifies text in the buffer
        !!xxd -b    " Run xxd in binary mode on the text
Î                   " On every line...
 dW                 "   delete a WORD
   54|              "   Go to the 54'th character on this line
      D             "   And delete everything after the cursor
Í                   " Remove on every line...
  ó                 "   Any whitespace
 ß                  "   Including newlines

Ou...

V , 16 octets

ñéÑ~"qpx!!xxd -b

Essayez-le en ligne!

Production:

00000000: 11000011 10110001 11000011 10101001 11000011 10010001  ......
00000006: 01111110 00100010 01110001 01110000 01111000 00100001  ~"qpx!
0000000c: 00100001 01111000 01111000 01100100 00100000 00101101  !xxd -
00000012: 01100010 00001010                                      b.

OP a déclaré:

La sortie peut être dans n'importe quel format pratique.

Cela sort dans un format beaucoup plus pratique pour V: P (mais je ne sais pas si cela étire les règles)

James
la source
6

CJam , 20 octets

{s"_~"+{i2b8Te[}%}_~

Essayez-le en ligne!

Surpris de voir CJam gagner! on verra combien de temps ça dure ...

Esolanging Fruit
la source
4

05AB1E , 105 octets

0"D34çýÇbεDg•Xó•18в@ƶà©i7j0ìëR6ôRíć7®-jšTìJ1®<×ì]ð0:J"D34çýÇbεDg•Xó•18в@ƶà©i7j0ìëR6ôRíć7®-jšTìJ1®<×ì]ð0:J

05AB1E n'a pas de conversion UTF-8 intégrée, donc je dois tout faire manuellement ..

Essayez-le en ligne ou vérifiez qu'il s'agit d'une quine .

Explication:

-part:

Le plus court pour 05AB1E est celui-ci: 0"D34çý"D34çý( 14 octets ) fourni par @OliverNi . Ma réponse utilise en ajoutant à la version modifiée de ce Quine ...ici: 0"D34çý..."D34çý.... Une brève explication de ce quine:

0               # Push a 0 to the stack (can be any digit)
 "D34çý"        # Push the string "D34çý" to the stack
        D       # Duplicate this string
         34ç    # Push 34 converted to an ASCII character to the stack: '"'
            ý   # Join everything on the stack (the 0 and both strings) by '"'
                # (output the result implicitly)

Partie défi:

Maintenant, pour la partie défi du code. Comme je l'ai mentionné en haut, 05AB1E n'a pas de conversion intégrée UTF-8, donc je dois faire ces choses manuellement. J'ai utilisé cette source comme référence sur la façon de le faire: convertir manuellement les points de code unicode en UTF-8 et UTF-16 . Voici un bref résumé de celui concernant la conversion des caractères Unicode en UTF-8:

  1. Convertissez les caractères unicode en leurs valeurs unicode (c'est-à-dire "dЖ丽"devient [100,1046,20029])
  2. Convertissez ces valeurs unicode en binaire (c'est-à-dire [100,1046,20029]devient ["1100100","10000010110","100111000111101"])
  3. Vérifiez dans laquelle des plages suivantes les caractères sont:
    1. 0x00000000 - 0x0000007F (0-127): 0xxxxxxx
    2. 0x00000080 - 0x000007FF (128-2047): 110xxxxx 10xxxxxx
    3. 0x00000800 - 0x0000FFFF (2048-65535): 1110xxxx 10xxxxxx 10xxxxxx
    4. 0x00010000 - 0x001FFFFF (65536-2097151): 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Il existe également des plages de 5 ou 6 octets, mais laissons-les pour l'instant.

Le caractère dsera dans la première plage, donc 1 octet en UTF-8; le caractère Жest dans la deuxième plage, donc 2 octets en UTF-8; et le caractère est dans la troisième plage, donc 3 octets en UTF-8.

Le xdans le motif derrière lui est rempli du binaire de ces caractères, de droite à gauche. Ainsi, le d( 1100100) avec motif 0xxxxxxxdevient 01100100; le Ж( 10000010110) avec motif 110xxxxx 10xxxxxxdevient 11010000 10010110; et le ( 100111000111101) avec le motif 1110xxxx 10xxxxxx 10xxxxxxdevient 1110x100 10111000 10111101, après quoi le restant xsont remplacés par 0: 11100100 10111000 10111101.

Donc, cette approche que j'ai également utilisée dans mon code. Au lieu de vérifier les plages réelles, je regarde simplement la longueur du binaire et le compare à la quantité de xdans les modèles, car cela économise quelques octets.

Ç               # Convert each character in the string to its unicode value
 b              # Convert each value to binary
  ε             # Map over these binary strings:
   Dg           #  Duplicate the string, and get its length
     Xó•       #  Push compressed integer 8657
         18в    #  Converted to Base-18 as list: [1,8,12,17]
            @   #  Check for each if the length is >= to this value
                #  (1 if truthy; 0 if falsey)
   ƶ            #  Multiply each by their 1-based index
    à           #  Pop and get its maximum
     ©          #  Store it in the register (without popping)
   i            #  If it is exactly 1 (first range):
    7j          #   Add leading spaces to the binary to make it of length 7
      0ì        #   And prepend a "0"
   ë            #  Else (any of the other ranges):
    R           #   Reverse the binary
     6ô         #   Split it into parts of size 6
       Rí       #   Reverse it (and each individual part) back
    ć           #   Pop, and push the remainder and the head separated to the stack
     7®-        #   Calculate 7 minus the value from the register
        j       #   Add leading spaces to the head binary to make it of that length
         š      #   Add it at the start of the remainder-list again
    Tì          #   Prepend "10" before each part
      J         #   Join the list together
    1®<×        #   Repeat "1" the value from the register - 1 amount of times
        ì       #   Prepend that at the front
  ]             # Close both the if-else statement and map
   ð0:          # Replace all spaces with "0"
      J         # And join all modified binary strings together
                # (which is output implicitly - with trailing newline)

Voir cette réponse 05AB1E de mes (sections Comment compresser les grands entiers? Et comment les listes entières Compresser? ) Pour comprendre pourquoi •Xó•18вest [1,8,12,17].

Kevin Cruijssen
la source
3

JavaScript (Node.js) , 60 octets

-15 octets de @Neil et @Shaggy

f=_=>[...Buffer(`f=`+f)].map(x=>x.toString(2).padStart(8,0))

Essayez-le en ligne!

Luis felipe De jesus Munoz
la source
padStart(8,0)enregistre 2 octets.
Neil
La spécification permet à la sortie d'être dans n'importe quel format pratique afin que vous puissiez garder le mapet abandonner le joinpour sortir un tableau de bits
Shaggy
60 octets avec sortie sous forme de tableau d'octets.
Shaggy
Merci @Neil et @Shaggy !!
Luis felipe De jesus Munoz
2

Rouille , 187 octets

fn f(o:u8){for c in b"go!g)n;t9(zgns!b!ho!c#%#/huds)(zhg!b_n <27zqshou )#z;19c|#-b_n(:|dmrdzg)1(:|||go!l`ho)(zg)0(:|".iter(){if c^o!=36{print!("{:08b}",c^o);}else{f(0);}}}fn main(){f(1);}

Essayez-le en ligne!

NieDzejkob
la source
2

Perl 6 , 46 octets

<say "<$_>~~.EVAL".ords.fmt("%08b",'')>~~.EVAL

Essayez-le en ligne!

Le quine standard avec .fmt("%08b",'')formate la liste des valeurs ordinales en longueur binaire 8 et joint avec une chaîne vide.

Jo King
la source
2

Perl 5, 42 octets

$_=q(say unpack'B*',"\$_=q($_);eval");eval

TIO

Nahuel Fouilleul
la source
2

Java 10, 339 308 265 227 225 186 184 184 octets

v->{var s="v->{var s=%c%s%1$c;return 0+new java.math.BigInteger(s.format(s,34,s).getBytes()).toString(2);}";return 0+new java.math.BigInteger(s.format(s,34,s).getBytes()).toString(2);}

-8 octets grâce à @NahuelFouilleul supprimant l'inutile &255(et un supplémentaire -35 pour avoir attiré mon attention sur le fait que les spécifications complètes du programme du défi avaient été révoquées et qu'une fonction est désormais autorisée également.)
-41 octets grâce à @ OlivierGrégoire .

Essayez-le en ligne.

Explication:

-part:

  • var s contient la chaîne de code source non formatée
  • %s est utilisé pour mettre cette chaîne en elle-même avec s.format(...)
  • %c, %1$cEt 34sont utilisés pour formater les guillemets doubles ( ")
  • s.format(s,34,s) met tout cela ensemble

Partie défi:

v->{                         //  Method with empty unused parameter and String return-type
  var s="...";               //   Unformatted source code String
  return 0+                  //   Return, with a leading "0":
   new java.math.BigInteger( //    A BigInteger of:
     s.format(s,34,s)        //     The actual source code String
      .getBytes())           //     Converted to a list of bytes (UTF-8 by default)
   .toString(2);}            //    And convert this BigInteger to a binary-String      
Kevin Cruijssen
la source
1
265 octets utilisant lambda, également parce que toute la source est ascii semble non signé int c&255n'est pas nécessaire
Nahuel Fouilleul
@NahuelFouilleul La question d'origine indiquait " Vous devez construire un programme complet. " Et " Votre sortie doit être imprimée sur STDOUT. ", D'où le code de plaque de bordure verbeux que j'ai au lieu d'une fonction lambda renvoyant une chaîne. Bon point de ne pas avoir besoin &255cependant car nous n'utilisons aucun caractère non ASCII, merci!
Kevin Cruijssen
ok je ne suis pas encore très familier avec les usages, mais d'autres langages comme javascript donnent un lambda renvoyant une chaîne, aussi je ne comprends pas pourquoi en java nous ne comptons pas le type et le point-virgule final lors de l'utilisation de lambda où pourrais-je trouver des règles?
Nahuel Fouilleul
1
Eh bien, c'est là que je suis perdu. Cependant j'ai essayé et voici un nouveau candidat pour 184 octets . Dites-moi si je me trompe quelque part;)
Olivier Grégoire
1
@ OlivierGrégoire Ah, belle approche! J'ai complètement oublié d' BigIntegerêtre assez court pour la conversion en chaînes binaires. Et 2 octets supplémentaires en changeant le return'0'+en return 0+. Hmm, pourquoi ce leader est-il 0nécessaire? Cela m'embrouille que toutes les chaînes binaires internes aient ce 0début, mais le tout premier pas lors de l'utilisation BigInteger.toString(2)..
Kevin Cruijssen
2

Python 2 , 68 67 octets

_="print''.join(bin(256|ord(i))[3:]for i in'_=%r;exec _'%_)";exec _

Essayez-le en ligne!

Une modification de cette réponse

-1 octets en supprimant l'espace après 'in' (merci @mdahmoune)

MilkyWay90
la source
-1 octet: vous pouvez supprimer l'espace aprèsin
mdahmoune
vous n'avez pas mis à jour votre lien TIO. aussi, j'ai essayé de faire à la '%08b'%ord(i)place de bin(256|ord(i))[3:], mais cela n'a pas fonctionné pour une raison quelconque
Jo King
2

R , 138 114 octets

x=function(){rev(rawToBits(rev(charToRaw(sprintf("x=%s;x()",gsub("\\s","",paste(deparse(x),collapse="")))))))};x()

Essayez-le en ligne!

Utilise la capacité de R à analyser les fonctions de leur représentation de caractère. Les revs sont nécessaires car ils rawToBitsplacent le bit le moins significatif en premier. as.integerest nécessaire car sinon les bits sont affichés avec un zéro non significatif.

Modifié une fois que j'ai réalisé que toute sortie pratique était autorisée. Également sorti par un sur le nombre d'octets d'origine.

Nick Kennedy
la source
1

C # (Visual C # Interactive Compiler) , 221 octets

var s="var s={0}{1}{0};Write(string.Concat(string.Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));";Write(string.Concat(string.Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));

Essayez-le en ligne!

C # (Visual C # Interactive Compiler) avec indicateur /u:System.String, 193 octets

var s="var s={0}{1}{0};Write(Concat(Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));";Write(Concat(Format(s,(char)34,s).Select(z=>Convert.ToString(z,2).PadLeft(8,'0'))));

Essayez-le en ligne!

Incarnation de l'ignorance
la source
1

Outils Bash + GNU, 48 octets

trap -- 'trap|xxd -b|cut -b9-64|tr -dc 01' EXIT

TIO

Nahuel Fouilleul
la source
merci, mis à jour en effet c'est la variation la plus courte sinon il faudrait supprimer de la sortie du piège
Nahuel Fouilleul