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 має функцію AND, яка може бути закодована як 01011110або 0010011100100010в UTF-8 (вони виглядають досить однаково: ^vs )
Adám

1
Кращий приклад: 01111100і 0010001100100010кодувати, |і .
Adám

4
@ Adám Я думаю, що було б справедливо вивести будь-яку двійкову послідовність, яка відповідає символу, який буде компілювати / запускати в певній реалізації мови.
qwr

1
Як щодо машинного коду? (Commodore C64 займає 28 байт, вважаючи, що сам машинний код є "джерелом")
Martin Rosenau

Відповіді:


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, тому мені доводиться робити все вручну ..

Спробуйте в Інтернеті або переконайтеся, що це квитка .

Пояснення:

-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) з малюнком ; ( ) З візерунком стає ; і ( ) з малюнком стає , після чого інші замінюються : .0xxxxxxx01100100Ж10000010110110xxxxx 10xxxxxx11010000 100101101001110001111011110xxxx 10xxxxxx 10xxxxxx1110x100 10111000 10111101x011100100 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 !!
Luis felipe De




2

Java 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, здається, не підписаний int c&255не потрібен
Nahuel Fouilleul

@NahuelFouilleul У початковому запитанні було вказано " Ви повинні побудувати повну програму " і " Ваш вихід повинен бути надрукований в STDOUT ". Отже, код у докладному бордюрі я маю замість лямбда-функції, що повертає String. Хороший момент про те, що нам не потрібно, &255оскільки ми не використовуємо жодних символів, що не належать до ASCII, дякую!
Kevin Cruijssen

Гаразд, я ще не дуже знайомий зі звичаями, але інші мови, такі як javascript, дають лямбда, що повертає рядок, також я не розумію, чому в Java ми не враховуємо тип і остаточну крапку з комою при використанні лямбда, де я міг би знайти правила?
Nahuel Fouilleul

1
Ну, там я загубився. Однак я спробував і ось новий кандидат на 184 байти . Скажіть, чи я десь помиляюся;)
Олів'є

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

2

Пітон 2 , 68 67 байт

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

Спробуйте в Інтернеті!

Модифікація цієї відповіді

-1 байт, видаливши пробіл після "in" (спасибі @mdahmoune)


-1 байт: u може скинути простір післяin
mdahmoune

ви не оновили посилання на 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 відхиляти функції від їх представлення символів. В revs необхідні , тому що rawToBitsставить найменш значимий біт перший. as.integerпотрібен, тому що в іншому випадку біти відображаються з провідним нулем.

Після редагування я зрозумів, що будь-який зручний вихід дозволений. Також було виведено одним за початковим числом байтів.


1

C # (Visual C # Interactive Compiler) , 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 # Interactive Compiler) з прапором /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

ТІО


дякую, оновлено дійсно, це найкоротша варіація, інакше її слід видалити з виходу пастки
Nahuel Fouilleul
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.