Quine tự xuất ra trong nhị phân


10

Nhiệm vụ của bạn, nếu bạn muốn chấp nhận nó, là viết một chương trình xuất ra mã nguồn của chính nó trong biểu diễn UTF-8 nhị phân .

Quy tắc

  • Nguồn phải dài ít nhất 1 byte.

  • Chương trình của bạn không được lấy đầu vào (hoặc có đầu vào trống, không sử dụng).

  • Đầu ra có thể ở bất kỳ định dạng đối tượng.

  • Dòng mới tùy chọn được cho phép.

  • Lưu ý rằng một byte là 8 bit và độ dài của biểu diễn UTF-8 nhị phân nhất thiết phải là bội số của 8.

  • Đây là để áp dụng tất cả các quy tắc chơi gôn thông thường và mã ngắn nhất (tính bằng byte) sẽ thắng.

  • Sơ hở tiêu chuẩn bị cấm.

Thí dụ

Giả sử mã nguồn của bạn là Aä$$€h, biểu diễn nhị phân UTF-8 tương ứng của nó là 010000011100001110100100001001000010010011100010100000101010110001101000.

Nếu tôi chạy Aä$$€hđầu ra phải được 010000011100001110100100001001000010010011100010100000101010110001101000.

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

Chuyển đổi chuỗi sang nhị phân UTF-8


1
Theo "nhị phân", bạn có nghĩa là một chuỗi đại diện cho các giá trị nhị phân, tức là một chuỗi chỉ bao gồm 1 và 0?

1
@mdahmoune Bây giờ điều đó đã tốt hơn nhiều. Câu hỏi vẫn là làm thế nào để thể hiện một cái gì đó như UTF-8. Lưu ý rằng biểu diễn Unicode chủ yếu dựa trên ngoại hình của một ký tự (chỉ thỉnh thoảng dựa trên ý nghĩa ngữ nghĩa). Điều gì nếu không có Unicode glyph được gán trông giống như một ký tự trong mã nguồn? Unicode cũng có nhiều điểm giống nhau (homoglyphs). Làm thế nào để một người quyết định sử dụng một? Ví dụ: Dyalog APL có chức năng AND có thể được mã hóa dưới dạng 01011110hoặc 0010011100100010trong UTF-8 (chúng trông khá giống nhau: ^vs )
Adám

1
Ví dụ tốt hơn: 011111000010001100100010mã hóa |.
Adám

4
@ Adám Tôi nghĩ sẽ công bằng khi đưa ra bất kỳ chuỗi nhị phân nào tương ứng với một biểu tượng sẽ biên dịch / chạy trong một triển khai ngôn ngữ nhất định.
qwr

1
Làm thế nào về mã máy? (Commodore C64 mất 28 byte với giả sử mã máy là "nguồn")
Martin Rosenau

Câu trả lời:


7

V , 28 (hoặc 16?) Latin 1 byte (35 byte UTF-8)

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

Hãy thử trực tuyến!

Hexdump (bằng tiếng Latin 1):

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

Đầu ra (biểu diễn nhị phân của cùng một mã trong UTF-8, không phải Latin 1):

110000111011000111000011101010011100001110010001011111100010001001110001011100000111100000100001001000010111100001111000011001000010000000101101011000100000110111000011100011100110010001010111001101010011010001111100010001000000110111000011100011011100001110011111110000111011001100001010

Giải trình:

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

Hoặc là...

V , 16 byte

ñéÑ~"qpx!!xxd -b

Hãy thử trực tuyến!

Đầu ra:

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 nói:

Đầu ra có thể ở bất kỳ định dạng thuận tiện.

Điều này xuất ra ở định dạng thuận tiện hơn nhiều cho V: P (nhưng tôi không chắc liệu điều đó có kéo dài quy tắc không)



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 không có nội dung chuyển đổi UTF-8, vì vậy tôi phải làm mọi thứ thủ công ..

Hãy thử trực tuyến hoặc xác minh rằng đó là một câu hỏi .

Giải trình:

-part:

Ngắn nhất cho 05AB1E là một trong những điều này: 0"D34çý"D34çý( 14 byte ) được cung cấp bởi @OliverNi . Câu trả lời của tôi sử dụng một phiên bản sửa đổi của câu hỏi đó bằng cách thêm vào ...đây : 0"D34çý..."D34çý.... Một lời giải thích ngắn về câu hỏi này:

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)

Phần thử thách:

Bây giờ cho phần thử thách của mã. Như tôi đã đề cập ở trên, 05AB1E không có nội dung chuyển đổi UTF-8, vì vậy tôi phải thực hiện những việc này một cách thủ công. Tôi đã sử dụng nguồn này làm tài liệu tham khảo về cách thực hiện điều đó: Chuyển đổi thủ công mã điểm unicode thành UTF-8 và UTF-16 . Dưới đây là một bản tóm tắt ngắn về việc chuyển đổi các ký tự Unicode thành UTF-8:

  1. Chuyển đổi các ký tự unicode thành các giá trị unicode của chúng (nghĩa là "dЖ丽"trở thành [100,1046,20029])
  2. Chuyển đổi các giá trị unicode này thành nhị phân (nghĩa là [100,1046,20029]trở thành ["1100100","10000010110","100111000111101"])
  3. Kiểm tra xem các ký tự trong phạm vi nào sau đây:
    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

Ngoài ra còn có phạm vi cho 5 hoặc 6 byte, nhưng bây giờ chúng ta hãy loại bỏ chúng.

Ký tự dsẽ ở trong phạm vi đầu tiên, do đó, 1 byte trong UTF-8; ký tự Жnằm trong phạm vi thứ hai, vì vậy 2 byte trong UTF-8; và ký tự nằm trong phạm vi thứ ba, vì vậy 3 byte trong UTF-8.

Trong xmô hình đằng sau nó chứa đầy nhị phân của các ký tự này, từ phải sang trái. Vì vậy, d( 1100100) với mẫu 0xxxxxxxtrở thành 01100100; các Ж( 10000010110) với mô hình 110xxxxx 10xxxxxxtrở nên 11010000 10010110; và ( 100111000111101) với mẫu 1110xxxx 10xxxxxx 10xxxxxxtrở thành 1110x100 10111000 10111101, sau đó phần còn lại xđược thay thế bằng 0: 11100100 10111000 10111101.

Vì vậy, cách tiếp cận đó tôi cũng đã sử dụng trong mã của mình. Thay vì kiểm tra phạm vi thực tế, tôi chỉ nhìn vào độ dài của nhị phân và so sánh nó với số lượng xtrong các mẫu, tuy nhiên, điều đó tiết kiệm một vài 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)

Xem 05AB1E câu trả lời này của tôi (phần Làm thế nào để nén các số nguyên lớn?Làm thế nào để liệt kê số nguyên nén? ) Để hiểu tại sao •Xó•18в[1,8,12,17].


3

JavaScript (Node.js) , 60 byte

-15 byte từ @Neil và @Shaggy

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

Hãy thử trực tuyến!


padStart(8,0)tiết kiệm 2 byte.
Neil

Thông số kỹ thuật cho phép đầu ra ở bất kỳ định dạng thuận tiện nào để bạn có thể giữ mapvà bỏ qua joinđể xuất ra một mảng bit
Shaggy

60 byte với đầu ra là một mảng byte.
Xù xì

Cảm ơn @Neil và @Shaggy !!
Luis felipe De jesus Munoz

2

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

Hãy thử trực tuyến!


2

Perl 6 , 46 byte

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

Hãy thử trực tuyến!

Các quine tiêu chuẩn với .fmt("%08b",'')định dạng danh sách các giá trị thứ tự thành chiều dài 8 nhị phân và nối với một chuỗi rỗng.



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 nhờ @NahuelFouilleul loại bỏ những thứ không cần thiết &255(và thêm -35 để làm tôi chú ý rằng các thông số kỹ thuật đầy đủ của chương trình đã bị thu hồi và giờ đây cũng được phép sử dụng chức năng ..)
-41 byte nhờ @ OlivierGrégoire .

Hãy thử trực tuyến.

Giải trình:

-part:

  • var s chứa chuỗi mã nguồn chưa được định dạng
  • %s được sử dụng để đặt Chuỗi này vào chính nó với s.format(...)
  • %c, %1$c34được sử dụng để định dạng dấu nháy kép ( ")
  • s.format(s,34,s) đặt tất cả lại với nhau

Phần thử thách:

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 sử dụng lambda, cũng bởi vì tất cả các nguồn là ascii dường như c&255không cần int int
Nahuel Fouilleul

@NahuelFouilleul Câu hỏi ban đầu cho biết " Bạn phải xây dựng một chương trình đầy đủ. " Và " Đầu ra của bạn phải được in thành STDOUT. ", Do đó, mã biên giới dài dòng tôi có thay vì hàm lambda trả về Chuỗi. &255Tuy nhiên, điểm hay về việc không cần vì chúng tôi không sử dụng bất kỳ ký tự không phải ASCII nào, cảm ơn!
Kevin Cruijssen

ok Tôi chưa quen lắm với các cách sử dụng, nhưng các ngôn ngữ khác như javascript cung cấp cho lambda một chuỗi, tôi cũng không hiểu tại sao trong java chúng ta không đếm loại và dấu chấm phẩy cuối cùng khi sử dụng lambda tôi có thể tìm quy tắc?
Nahuel Fouilleul

1
Chà, đó là nơi tôi lạc lối. Tuy nhiên tôi đã thử và đây là một ứng cử viên mới cho 184 byte . Nói cho tôi biết nếu tôi sai ở đâu đó;)
Olivier Grégoire

1
@ OlivierGrégoire Ah, cách tiếp cận tốt đẹp! Hoàn toàn quên mất việc BigIntegerkhá ngắn để chuyển đổi sang chuỗi nhị phân. Và thêm 2 byte bằng cách thay đổi return'0'+thành return 0+. Hmm, tại sao đó là 0btw cần thiết hàng đầu ? Nó làm tôi bối rối rằng tất cả các chuỗi nhị phân bên trong đều có đầu này 0, nhưng cái đầu tiên không phải khi sử dụng BigInteger.toString(2)..
Kevin Cruijssen

2

Python 2 , 68 67 byte

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

Hãy thử trực tuyến!

Một sửa đổi của câu trả lời này

-1 byte bằng cách xóa khoảng trắng sau 'in' (cảm ơn @mdahmoune)


-1 byte: bạn có thể thả khoảng trống sauin
mdahmoune

bạn chưa cập nhật liên kết TIO của bạn. Ngoài ra, tôi đã cố gắng làm '%08b'%ord(i)thay vì bin(256|ord(i))[3:], nhưng nó không hoạt động vì một số lý do
Jo King

2

R , 138 114 byte

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

Hãy thử trực tuyến!

Sử dụng khả năng của R để làm suy yếu các chức năng để thể hiện nhân vật của họ. Các revs là cần thiết bởi vì rawToBitsđặt bit ít quan trọng nhất đầu tiên. as.integerlà cần thiết bởi vì nếu không các bit được hiển thị với số 0 đứng đầu.

Chỉnh sửa một khi tôi nhận ra rằng bất kỳ đầu ra thuận tiện đều được cho phép. Cũng được đưa ra bởi một trong số byte ban đầu.


1

C # (Trình biên dịch tương tác Visual C #) , 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'))));

Hãy thử trực tuyến!

C # (Trình biên dịch tương tác Visual C #) với cờ /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'))));

Hãy thử trực tuyến!


1

Công cụ Bash + GNU, 48 byte

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

TIO


cảm ơn, cập nhật thực sự đó là biến thể ngắn nhất nếu không nên xóa khỏi đầu ra bẫy
Nahuel Fouilleul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.