Quine выводит себя в двоичном виде


10

Ваша задача, если вы хотите принять это, - написать программу, которая выводит собственный исходный код в двоичном представлении UTF-8 .

правила

  • Источник должен иметь длину не менее 1 байта.

  • Ваша программа не должна принимать данные (или иметь неиспользуемые пустые данные).

  • Вывод может быть в любом удобном формате.

  • Необязательный трейлинг перевод строки разрешен.

  • Обратите внимание, что один байт равен 8 битам, а длина двоичного представления UTF-8 обязательно кратна 8.

  • Это поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).

  • Стандартные лазейки запрещены.

пример

Допустим, ваш исходный код Aä$$€hсоответствует бинарному представлению UTF-8 010000011100001110100100001001000010010011100010100000101010110001101000.

Если я бегу, Aä$$€hто вывод должен быть 010000011100001110100100001001000010010011100010100000101010110001101000.

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

Преобразователи строки в двоичные UTF-8


1
Под «двоичным» вы подразумеваете строковое представление двоичных значений, то есть строку, состоящую только из 1 и 0?

1
@mdahmoune Теперь это уже намного лучше. Остается вопрос, как представить что-то как UTF-8. Обратите внимание, что представление Unicode в основном основано на внешности символа (только иногда на семантическом значении). Что если ни один из назначенных символов Unicode не выглядит как символ в исходном коде? Unicode также имеет много похожих друг на друга (гомоглифов). Как решить, какой использовать? Например Dyalog APL имеет и функцию , которая может быть закодирован как 01011110и 0010011100100010в UTF-8 (они выглядят довольно похожи: ^против )
адам

1
Лучший пример: 01111100и 0010001100100010закодировать |и .
Адам

4
@ Adám Я думаю, было бы справедливо вывести любую двоичную последовательность, которая соответствует символу, который будет компилироваться / выполняться в определенной реализации языка.
19

1
Как насчет машинного кода? (Commodore C64 занимает 28 байтов, предполагая, что сам «машинный код» является «источником»)
Мартин Розенау

Ответы:


7

V , 28 (или 16?) Латинских 1 байт (35 UTF-8 байт)

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

Попробуйте онлайн!

Hexdump (на латыни 1):

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

Вывод (двоичное представление одного и того же кода в UTF-8, а не в латинице 1):

110000111011000111000011101010011100001110010001011111100010001001110001011100000111100000100001001000010111100001111000011001000010000000101101011000100000110111000011100011100110010001010111001101010011010001111100010001000000110111000011100011011100001110011111110000111011001100001010

Объяснение:

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

Или...

V , 16 байтов

ñéÑ~"qpx!!xxd -b

Попробуйте онлайн!

Вывод:

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.

ОП сказал:

Вывод может быть в любом удобном формате.

Это приводит к гораздо более удобному формату для V: P (но я не уверен, что это нарушает правила)



4

05AB1E , 105 байт

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 не имеет встроенных преобразований UTF-8, поэтому я должен делать все вручную ..

Попробуйте онлайн или убедитесь, что это Quine .

Объяснение:

-part:

Кратчайшее для 05AB1E это один: 0"D34çý"D34çý( 14 байт ) обеспечивается @OliverNi . Мой ответ использует модифицированную версию этого Куайно, добавив на ...здесь: 0"D34çý..."D34çý.... Краткое объяснение этой сущности:

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)

Задача часть:

Теперь о сложной части кода. Как я упоминал выше, 05AB1E не имеет встроенных преобразований UTF-8, поэтому я должен делать это вручную. Я использовал этот источник в качестве справки о том, как это сделать: ручное преобразование кодов Unicode в UTF-8 и UTF-16 . Вот краткое изложение того, что касается преобразования символов Unicode в UTF-8:

  1. Преобразуйте символы Unicode в их значения Unicode (то есть "dЖ丽"становится [100,1046,20029])
  2. Преобразовать эти значения Unicode в двоичные (то есть [100,1046,20029]становится ["1100100","10000010110","100111000111101"])
  3. Проверьте, в каком из следующих диапазонов находятся символы:
    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

Также есть диапазоны для 5 или 6 байтов, но давайте пока их не будем использовать.

Символ dбудет в первом диапазоне, поэтому 1 байт в UTF-8; символ Жнаходится во втором диапазоне, поэтому 2 байта в UTF-8; и символ находится в третьем диапазоне, поэтому 3 байта в UTF-8.

xВ образце за ней заполняются двоичным эти символы, справа налево. Таким образом, d( 1100100) с шаблоном 0xxxxxxxстановится 01100100; Ж( 10000010110) с узором 110xxxxx 10xxxxxxстановится 11010000 10010110; и ( 100111000111101) с рисунком 1110xxxx 10xxxxxx 10xxxxxxстановится 1110x100 10111000 10111101, после чего остальные xзаменяются 0: 11100100 10111000 10111101.

Таким образом, этот подход я также использовал в своем коде. Вместо того, чтобы проверять фактические диапазоны, я просто смотрю на длину двоичного файла и сравниваю его с количеством xв шаблонах, поскольку это экономит несколько байтов.

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

Смотрите этот 05AB1E ответ моих (разделы Как сжать большие целые числа? И Как сжать целые списки? ) , Чтобы понять , почему •Xó•18вэто [1,8,12,17].


3

JavaScript (Node.js) , 60 байт

-15 байтов от @Neil и @Shaggy

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

Попробуйте онлайн!


padStart(8,0)экономит 2 байта.
Нил

Спецификация позволяет выводить данные в любом удобном формате, чтобы вы могли сохранить mapи joinисключить массив для вывода массива битов
Shaggy

60 байтов с выводом в виде массива байтов.
Лохматый

Спасибо @Neil и @Shaggy !!
Луис Фелипе Де Иисус Муньос


2

Perl 6 , 46 байт

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

Попробуйте онлайн!

Стандартный quine .fmt("%08b",'')форматирует список порядковых значений в двоичный файл длиной 8 и объединяет его пустой строкой.



2

Ява 10, 339 308 265 227 225 186 184 байта

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 байт благодаря @NahuelFouilleul, удаляющему ненужные &255(и еще -35, чтобы привлечь мое внимание к тому, что полные технические характеристики программы были отозваны, а функция теперь также разрешена).
-41 байт благодаря @ OlivierGrégoire ,

Попробуйте онлайн.

Объяснение:

-part:

  • var s содержит неформатированный исходный код String
  • %s используется, чтобы поместить эту строку в себя с s.format(...)
  • %c, %1$cИ 34используются для форматирования двойных кавычек (" )
  • s.format(s,34,s) складывает все вместе

Задача часть:

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      

1
265 байт, использующих лямбду, также потому, что весь источник ascii, кажется, unsigned int c&255не нужен
Nahuel Fouilleul

@NahuelFouilleul В первоначальном вопросе говорилось: « Вы должны построить полную программу. » И « Ваш вывод должен быть распечатан в STDOUT. », Поэтому у меня есть подробный код границы, который я имею вместо лямбда-функции, возвращающей строку. Хорошая мысль о том, что в этом нет необходимости, &255так как мы не используем символы не ASCII, спасибо!
Кевин Круйссен

Хорошо, я еще не очень знаком с использованием, но другие языки, такие как javascript, дают лямбду, возвращающую строку, также я не понимаю, почему в java мы не учитываем тип и конечную точку с запятой при использовании лямбды, где я могу найти правила?
Науэль Фуйе

1
Ну, вот где я потерялся. Однако я попробовал и вот новый кандидат на 184 байта . Скажи мне, если я где-то не прав;)
Оливье Грегуар

1
@ OlivierGrégoire Ах, хороший подход! Полностью забыл о том, BigIntegerчтобы быть довольно коротким для преобразования в двоичные строки. И еще 2 байта путем изменения return'0'+в return 0+. Хм, почему это 0ведение необходимо между прочим? Меня смущает то, что все внутренние двоичные строки имеют это ведущее 0, но самое первое не при использовании BigInteger.toString(2)..
Кевин Круйссен

2

Python 2 , 68 67 байт

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

Попробуйте онлайн!

Модификация этого ответа

-1 байт, удаляя пробел после 'in' (спасибо @mdahmoune)


-1 байт: вы можете in
оставить

Вы не обновили свою ссылку TIO. Кроме того, я попытался сделать '%08b'%ord(i)вместо bin(256|ord(i))[3:], но по некоторым причинам это не сработало
Джо Кинг

2

R , 138 114 байт

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

Попробуйте онлайн!

Использует способность R разбирать функции до их символьного представления. С revнужны потому чтоrawToBits ставит наименее значимый бит первый. as.integerнеобходимо, потому что в противном случае биты отображаются с начальным нулем.

После редактирования я понял, что любой удобный вывод разрешен. Также был один на исходный счетчик байтов.


1

C # (интерактивный компилятор Visual C #) , 221 байт

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

Попробуйте онлайн!

C # (интерактивный компилятор Visual C #) с флагом /u:System.String, 193 байта

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

Попробуйте онлайн!


1

Инструменты Bash + GNU, 48 байт

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

TIO


спасибо, обновил, действительно, это самый короткий вариант, в противном случае его следует удалить из вывода ловушки
Науэль Фуйе
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.