Quine produz-se em binário


10

Sua tarefa, se você deseja aceitá-la, é escrever um programa que produz seu próprio código-fonte na representação binária UTF-8 .

Regras

  • A fonte deve ter pelo menos 1 byte de comprimento.

  • Seu programa não deve receber entrada (ou ter uma entrada vazia não utilizada).

  • A saída pode estar em qualquer formato conveniente.

  • Nova linha à direita opcional é permitida.

  • Observe que um byte tem 8 bits e o comprimento da representação binária UTF-8 é necessariamente um múltiplo de 8.

  • Isso é portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.

  • As brechas padrão são proibidas.

Exemplo

Digamos que seu código-fonte seja Aä$$€h, sua representação binária UTF-8 correspondente é 010000011100001110100100001001000010010011100010100000101010110001101000.

Se eu executar Aä$$€ha saída deve ser 010000011100001110100100001001000010010011100010100000101010110001101000.

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

String para conversores binários UTF-8


11
Por "binário", você quer dizer uma representação de string dos valores binários, ou seja, uma string que consiste em apenas 1 e 0?

11
@mdahmoune Agora isso já é muito melhor. A questão permanece como representar algo como UTF-8. Observe que a representação Unicode é baseada principalmente na aparência de um personagem (apenas ocasionalmente no significado semântico). E se nenhum glifo Unicode atribuído se parecer com um caractere no código-fonte? O Unicode também tem muitos itens parecidos (homoglifos). Como alguém decide qual usar? Por exemplo Dyalog APL tem uma função AND que pode ser codificado como 01011110ou 0010011100100010em UTF-8 (eles parecem muito parecidos: ^vs )
Adám

11
Melhor exemplo: 01111100e 0010001100100010codifique |e .
Adám 04/02/19

4
@ Adám Eu acho que seria justo produzir qualquer sequência binária que corresponda a um símbolo que será compilado / executado em uma determinada implementação de uma linguagem.
Qd #

11
E o código da máquina? (Commodore C64 leva 28 bytes assumindo que o código de máquina em si é a "fonte")
Martin Rosenau

Respostas:


7

V , 28 (ou 16?) Latina 1 bytes (35 bytes UTF-8)

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

Experimente online!

Hexdump (em latim 1):

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

Saída (representação binária do mesmo código em UTF-8, não em latim 1):

110000111011000111000011101010011100001110010001011111100010001001110001011100000111100000100001001000010111100001111000011001000010000000101101011000100000110111000011100011100110010001010111001101010011010001111100010001000000110111000011100011011100001110011111110000111011001100001010

Explicação:

ñéÑ~"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 bytes

ñéÑ~"qpx!!xxd -b

Experimente online!

Resultado:

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 disse:

A saída pode estar em qualquer formato conveniente.

Isso gera um formato muito mais conveniente para V: P (mas não tenho certeza se isso está estendendo as regras)



4

05AB1E , 105 bytes

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ão possui built-in de conversão UTF-8, por isso tenho que fazer tudo manualmente .

Experimente on-line ou verifique se é um problema .

Explicação:

-part:

O mais curto para 05AB1E é este: 0"D34çý"D34çý( 14 bytes ) fornecido por @OliverNi . Minha resposta utiliza uma versão modificada do que Quine, adicionando ao ...aqui: 0"D34çý..."D34çý.... Uma breve explicação sobre esse 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)

Parte do desafio:

Agora, para a parte do desafio do código. Como mencionei na parte superior, o 05AB1E não possui built-in de conversão UTF-8, por isso tenho que fazer essas coisas manualmente. Eu usei esta fonte como referência sobre como fazer isso: Converter manualmente pontos de código unicode em UTF-8 e UTF-16 . Aqui está um breve resumo sobre a conversão de caracteres Unicode em UTF-8:

  1. Converta os caracteres unicode em seus valores unicode (ou seja, "dЖ丽"torna-se [100,1046,20029])
  2. Converta esses valores unicode em binários (ou seja, [100,1046,20029]torna-se ["1100100","10000010110","100111000111101"])
  3. Verifique em qual dos seguintes intervalos os caracteres são:
    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

Também existem intervalos para 5 ou 6 bytes, mas vamos deixá-los de fora por enquanto.

O personagem destará no primeiro intervalo, portanto, 1 byte em UTF-8; caractere Жestá no segundo intervalo, portanto, 2 bytes em UTF-8; e caractere está no terceiro intervalo, portanto, 3 bytes em UTF-8.

O xpadrão por trás dele é preenchido com o binário desses caracteres, da direita para a esquerda. Então o d( 1100100) com padrão 0xxxxxxxse torna 01100100; o Ж( 10000010110) com padrão 110xxxxx 10xxxxxxse torna 11010000 10010110; e o ( 100111000111101) com o padrão 1110xxxx 10xxxxxx 10xxxxxxse torna 1110x100 10111000 10111101, após o que os restantes xsão substituídas por 0: 11100100 10111000 10111101.

Então, essa abordagem também usei no meu código. Em vez de verificar os intervalos reais, basta olhar para o comprimento do binário e compará-lo com a quantidade de xpadrões no entanto, pois isso economiza alguns bytes.

Ç               # 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)

Veja este 05AB1E resposta meu (seções Como comprimir grandes inteiros? E Como listas inteiras compressa? ) Para entender por que •Xó•18вé [1,8,12,17].


3

JavaScript (Node.js) , 60 bytes

-15 bytes de @Neil e @Shaggy

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

Experimente online!


padStart(8,0)economiza 2 bytes.
Neil

A especificação permite a saída para estar em qualquer formato conveniente para que você possa manter o mape largou o joinpara a saída de uma matriz de bits
Shaggy

60 bytes com saída como uma matriz de bytes.
Shaggy

Obrigado @Neil e @Shaggy !!
Luis felipe De jesus Munoz

2

Ferrugem , 187 bytes

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);}

Experimente online!


2

Perl 6 , 46 bytes

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

Experimente online!

O quine padrão com .fmt("%08b",'')formata a lista de valores ordinais em binário de comprimento 8 e se junta a uma string vazia.



2

Java 10, 339 308 265 227 225 186 184 bytes

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 bytes graças a @NahuelFouilleul removendo o desnecessário &255(e -35 adicional para chamar à atenção que as especificações completas do programa do desafio foram revogadas e uma função também é permitida agora ..)
-41 bytes graças a @ OlivierGrégoire .

Experimente online.

Explicação:

-part:

  • var s contém o código-fonte não formatado String
  • %s é usado para colocar essa String em si mesma com s.format(...)
  • %c, %1$cE 34são usados para formatar as aspas duplas ( ")
  • s.format(s,34,s) coloca tudo junto

Parte do desafio:

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      

11
265 bytes usando lambda, também porque todas as fontes é ascii parece unsigned int c&255não é necessário
Nahuel FOUILLEUL

@NahuelFouilleul A pergunta original dizia " Você deve criar um programa completo " e " Sua saída deve ser impressa em STDOUT. ", Portanto, o código detalhado da placa de borda que eu tenho em vez de uma função lambda retornando uma String. &255No entanto, é bom não precisar, pois não usamos caracteres não-ASCII, obrigado!
Kevin Cruijssen

ok, eu ainda não sou muito familiarizado com os usos, mas outras linguagens como javascript fornecem um lambda retornando uma string, também não entendo por que em java não contamos o tipo e o ponto-e-vírgula final ao usar lambda onde eu poderia encontrar regras?
Nahuel Fouilleul 5/02/19

11
Bem, é aí que eu estou perdido. No entanto, eu tentei e aqui está um novo candidato para 184 bytes . Diga-me se eu estiver errado em algum lugar;):
Olivier Grégoire

11
@ OlivierGrégoire Ah, boa abordagem! Esqueci completamente de BigIntegerser muito pequeno para converter em strings binárias. E mais 2 bytes alterando return'0'+para return 0+. Hmm, por que essa liderança é 0necessária? Isso me confunde que todos os binários-cordas internas têm esse líder 0, mas o primeiro não quando usando BigInteger.toString(2)..
Kevin Cruijssen

2

Python 2 , 68 67 bytes

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

Experimente online!

Uma modificação desta resposta

-1 bytes removendo o espaço após 'in' (obrigado @mdahmoune)


-1 byte: u pode soltar o espaço depoisin
mdahmoune

você não atualizou seu link do TIO. Além disso, eu tentei fazer '%08b'%ord(i), em vez de bin(256|ord(i))[3:], mas não funcionou por algum motivo
Jo rei

2

R , 138 114 bytes

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

Experimente online!

Usa a capacidade de R de separar funções para a representação de caracteres. Os revsão necessários porque rawToBitscoloca o bit menos significativo em primeiro lugar. as.integeré necessário porque, caso contrário, os bits são exibidos com um zero à esquerda.

Editado quando percebi que qualquer saída conveniente era permitida. Também foi eliminado por um na contagem de bytes original.


1

C # (Compilador interativo do Visual C #) , 221 bytes

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'))));

Experimente online!

C # (Visual C # Interactive Compiler) com sinalizador /u:System.String, 193 bytes

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'))));

Experimente online!


1

Ferramentas Bash + GNU, 48 bytes

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

TIO


graças, actualizado, de facto, é a variação menor de outra forma deve ser removido a partir da saída armadilha
Nahuel FOUILLEUL
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.