Quine menghasilkan sendiri dalam biner


10

Tugas Anda, jika Anda ingin menerimanya, adalah menulis program yang menampilkan kode sumbernya sendiri dalam representasi UTF-8 biner .

Aturan

  • Panjang sumber minimal harus 1 byte.

  • Program Anda tidak boleh mengambil input (atau memiliki input kosong yang tidak digunakan).

  • Output mungkin dalam format apa pun yang nyaman.

  • Newline trailing opsional diizinkan.

  • Perhatikan bahwa satu byte adalah 8 bit, dan panjang representasi biner UTF-8 adalah kelipatan dari 8.

  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.

  • Celah standar dilarang.

Contoh

Katakanlah kode sumber Anda Aä$$€h, representasi biner UTF-8 yang sesuai adalah010000011100001110100100001001000010010011100010100000101010110001101000 .

Jika saya menjalankan Aä$$€houtput harus 010000011100001110100100001001000010010011100010100000101010110001101000.

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

Konverter string ke biner UTF-8


1
Dengan "biner", maksud Anda representasi string dari nilai biner, yaitu string yang hanya terdiri dari 1 dan 0?

1
@mdahmoune Sekarang sudah jauh lebih baik. Pertanyaannya tetap bagaimana merepresentasikan sesuatu sebagai UTF-8. Perhatikan bahwa representasi Unicode terutama didasarkan pada penampilan karakter (hanya sesekali pada makna semantik). Bagaimana jika tidak ada mesin terbang Unicode ditugaskan terlihat seperti karakter dalam kode sumber? Unicode juga memiliki banyak kesamaan (homoglyphs). Bagaimana cara memutuskan mana yang akan digunakan? Misalnya Dyalog APL memiliki fungsi DAN yang dapat dikodekan sebagai 01011110atau 0010011100100010di UTF-8 (mereka terlihat sangat mirip: ^vs )
Adám

1
Contoh yang lebih baik: 01111100dan 0010001100100010menyandikan |dan .
Adám

4
@ Adm Saya pikir akan adil untuk menampilkan urutan biner yang sesuai dengan simbol yang akan dikompilasi / dijalankan dalam implementasi bahasa tertentu.
qwr

1
Bagaimana dengan kode mesin? (Commodore C64 mengambil 28 byte dengan asumsi kode mesin itu sendiri adalah "sumber")
Martin Rosenau

Jawaban:


7

V , 28 (atau 16?) Latin 1 byte (35 UTF-8 byte)

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

Cobalah online!

Hexdump (dalam bahasa Latin 1):

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

Output (representasi biner dari kode yang sama dalam UTF-8, bukan Latin 1):

110000111011000111000011101010011100001110010001011111100010001001110001011100000111100000100001001000010111100001111000011001000010000000101101011000100000110111000011100011100110010001010111001101010011010001111100010001000000110111000011100011011100001110011111110000111011001100001010

Penjelasan:

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

Atau...

V , 16 byte

ñéÑ~"qpx!!xxd -b

Cobalah online!

Keluaran:

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

Output mungkin dalam format apa pun yang nyaman.

Output ini dalam format yang jauh lebih nyaman untuk V: P (tapi saya tidak yakin apakah itu sesuai aturan)



4

05AB1E , 105 byte

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 tidak memiliki bawaan konversi UTF-8, jadi saya harus melakukan semuanya secara manual ..

Cobalah secara online atau verifikasi bahwa itu quine .

Penjelasan:

:

terpendek untuk 05AB1E adalah ini: 0"D34çý"D34çý( 14 byte ) disediakan oleh @OliverNi . Jawaban saya menggunakan versi modifikasi dari Quine bahwa dengan menambahkan di ...sini: 0"D34çý..."D34çý.... Penjelasan singkat tentang quine ini:

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)

Bagian tantangan:

Sekarang untuk bagian tantangan dari kode. Seperti yang saya sebutkan di atas, 05AB1E tidak memiliki builtin konversi UTF-8, jadi saya harus melakukan hal-hal ini secara manual. Saya telah menggunakan sumber ini sebagai referensi tentang cara melakukan itu: Mengubah secara otomatis unicode codepoint menjadi UTF-8 dan UTF-16 . Berikut ringkasan singkat tentang konversi karakter Unicode ke UTF-8:

  1. Ubah karakter unicode menjadi nilai unicode mereka (yaitu "dЖ丽"menjadi [100,1046,20029])
  2. Ubah nilai unicode ini menjadi biner (yaitu [100,1046,20029]menjadi ["1100100","10000010110","100111000111101"])
  3. Periksa di mana dari rentang berikut karakternya adalah:
    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

Ada juga rentang untuk 5 atau 6 byte, tetapi mari kita tinggalkan untuk saat ini.

Karakter dakan berada di kisaran pertama, jadi 1 byte di UTF-8; karakter Жberada di kisaran kedua, jadi 2 byte di UTF-8; dan karakter berada di kisaran ketiga, jadi 3 byte di UTF-8.

The xdalam pola di balik itu diisi dengan biner dari karakter ini, dari kanan ke kiri. Jadi d( 1100100) dengan pola 0xxxxxxxmenjadi 01100100; yang Ж( 10000010110) dengan pola 110xxxxx 10xxxxxxmenjadi 11010000 10010110; dan ( 100111000111101) dengan pola 1110xxxx 10xxxxxx 10xxxxxxmenjadi 1110x100 10111000 10111101, setelah itu sisanya xdiganti dengan 0: 11100100 10111000 10111101.

Jadi, pendekatan itu saya juga gunakan dalam kode saya. Alih-alih memeriksa rentang sebenarnya, saya hanya melihat panjang biner dan membandingkannya dengan jumlah xdalam pola, karena itu menghemat beberapa byte.

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

Lihat ini 05AB1E jawaban saya (bagian Cara kompres bilangan bulat besar? Dan Cara daftar bilangan bulat kompres? ) Untuk memahami mengapa •Xó•18вadalah [1,8,12,17].



2

Karat , 187 byte

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

Cobalah online!


2

Perl 6 , 46 byte

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

Cobalah online!

Quine standar dengan .fmt("%08b",'')memformat daftar nilai ordinal ke dalam biner panjang 8 dan bergabung dengan string kosong.



2

Java 10, 339 308 265 227 225 186 184 byte

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 byte berkat @NahuelFouilleul menghapus yang tidak perlu &255(dan tambahan -35 untuk menarik perhatian saya bahwa spesifikasi program penuh dari tantangan telah dicabut dan fungsi diizinkan sekarang juga ..)
-41 byte terima kasih kepada @ OlivierGrégoire .

Cobalah online.

Penjelasan:

:

  • var s berisi String kode sumber yang tidak diformat
  • %s digunakan untuk menempatkan String ini ke dalam dirinya dengan s.format(...)
  • %c, %1$cdan 34digunakan untuk memformat tanda kutip ganda (" )
  • s.format(s,34,s) menempatkan semuanya bersama-sama

Bagian tantangan:

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 byte menggunakan lambda, juga karena semua sumber ascii tampaknya tidak ditandatangani int c&255tidak diperlukan
Nahuel Fouilleul

@NahuelFouilleul Pertanyaan aslinya menyatakan " Anda harus membangun program lengkap. " Dan " Output Anda harus dicetak ke STDOUT. ", Maka kode perbatasan-verbose yang saya miliki alih-alih fungsi lambda mengembalikan sebuah String. Poin bagus tentang tidak perlu &255karena kami tidak menggunakan karakter non-ASCII, terima kasih!
Kevin Cruijssen

ok saya belum sangat terbiasa dengan penggunaan, tetapi bahasa lain seperti javascript memberikan lambda mengembalikan string, juga saya tidak mengerti mengapa di java kita tidak menghitung jenis dan titik koma akhir saat menggunakan lambda di mana saya bisa temukan aturan?
Nahuel Fouilleul

1
Nah, di situlah saya tersesat. Namun saya mencoba dan inilah kandidat baru untuk 184 byte . Katakan jika saya salah;)
Olivier Grégoire

1
@ OlivierGrégoire Ah, pendekatan yang bagus! Benar-benar lupa tentang BigIntegercukup singkat untuk mengkonversi ke binary-Strings. Dan 2 byte lagi dengan mengubah return'0'+to return 0+. Hmm, mengapa itu memimpin 0diperlukan? Ini membingungkan saya bahwa semua binary-Strings terdepan 0, tetapi yang pertama tidak saat menggunakan BigInteger.toString(2)..
Kevin Cruijssen

2

Python 2 , 68 67 byte

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

Cobalah online!

Modifikasi dari jawaban ini

-1 byte dengan menghapus spasi setelah 'in' (terima kasih @mdahmoune)


-1 byte: Anda dapat menghapus ruang setelahin
mdahmoune

Anda belum memperbarui tautan TIO Anda. juga, saya mencoba melakukan '%08b'%ord(i)alih - alih bin(256|ord(i))[3:], tetapi itu tidak berhasil karena beberapa alasan
Jo King

2

R , 138 114 byte

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

Cobalah online!

Menggunakan kemampuan R untuk menyebarkan fungsi ke representasi karakter mereka. The revs diperlukan karena rawToBitsmenempatkan sedikit signifikan pertama.as.integerdiperlukan karena jika tidak bit ditampilkan dengan nol di depan.

Diedit setelah saya menyadari bahwa output yang nyaman diizinkan. Juga keluar satu per satu pada hitungan byte asli.


1

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

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

Cobalah online!

C # (Visual C # Interactive Compiler) dengan flag /u:System.String, 193 byte

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

Cobalah online!


1

Alat Bash + GNU, 48 byte

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

TIO


terima kasih, diperbarui memang itu variasi terpendek jika tidak harus dihapus dari output perangkap
Nahuel Fouilleul
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.