ควินเอาท์พุทตัวเองในไบนารี


10

งานของคุณถ้าคุณต้องการที่จะยอมรับมันคือการเขียนโปรแกรมที่ส่งออกซอร์สโค้ดของตัวเองในการเป็นตัวแทนUTF-8แบบไบนารี

กฎระเบียบ

  • แหล่งที่มาจะต้องมีความยาวอย่างน้อย 1 ไบต์

  • โปรแกรมของคุณจะต้องไม่รับอินพุต (หรือมีอินพุตที่ไม่ได้ใช้และว่างเปล่า)

  • ผลลัพธ์อาจอยู่ในรูปแบบ Convient ใด ๆ

  • ขึ้นบรรทัดใหม่ตัวเลือกที่ได้รับอนุญาต

  • ขอให้สังเกตว่าหนึ่งไบต์คือ 8 บิตและความยาวของการแทนค่า UTF-8 แบบไบนารีนั้นจำเป็นต้องมีหลายเท่าของ 8

  • นี่คือเพื่อให้ใช้กฎการตีกอล์ฟตามปกติและรหัสที่สั้นที่สุด (เป็นไบต์) ชนะ

  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

ตัวอย่าง

สมมติว่ารหัสต้นฉบับของคุณเป็นAä$$€hที่สอดคล้อง UTF-8 แทน binary 010000011100001110100100001001000010010011100010100000101010110001101000ของมันคือ

ถ้าผมทำงานที่ส่งออกจะต้องเป็นAä$$€h010000011100001110100100001001000010010011100010100000101010110001101000

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

สตริงเป็นตัวแปลง UTF-8 แบบไบนารี


1
โดย "binary" คุณหมายถึงการเป็นตัวแทนสตริงของค่าไบนารีเช่นสตริงที่ประกอบด้วย 1 เท่านั้นและ 0 หรือไม่?

1
@mdahmoune ตอนนี้มันดีกว่ามากแล้ว คำถามนี้ยังคงแสดงวิธีการแทน UTF-8 ขอให้สังเกตว่าการเป็นตัวแทน Unicode นั้นขึ้นอยู่กับลักษณะของตัวละครเป็นหลัก จะเป็นอย่างไรถ้าไม่มี Unicode glyph ที่กำหนดให้ดูเหมือนอักขระในซอร์สโค้ด Unicode ยังมีลักษณะคล้ายกันหลายอย่าง (homoglyphs) คนจะตัดสินใจเลือกแบบไหนดี? เช่น Dyalog APL มีฟังก์ชั่น AND ซึ่งอาจจะเข้ารหัสเป็น01011110หรือ0010011100100010ใน UTF-8 (พวกมันดูค่อนข้างเหมือนกัน: ^vs )
Adám

1
ตัวอย่างที่ดี: 01111100และ0010001100100010เข้ารหัสและ|
Adám

4
@ Adam ฉันคิดว่ามันจะยุติธรรมที่จะออกลำดับไบนารีใด ๆ ที่สอดคล้องกับสัญลักษณ์ที่จะรวบรวม / เรียกใช้ในการใช้งานบางอย่างของภาษา
qwr

1
แล้วรหัสเครื่องล่ะ (พลเรือจัตวา 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.

OP กล่าวว่า

ผลลัพธ์อาจอยู่ในรูปแบบที่สะดวก

เอาต์พุตนี้ในรูปแบบที่สะดวกกว่าสำหรับ 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 ดังนั้นฉันต้องทำทุกอย่าง ด้วยตนเอง ..

ลองออนไลน์หรือตรวจสอบว่ามันเป็นควิน

คำอธิบาย:

:

ใก้ลสำหรับ 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 ดังนั้นฉันต้องทำสิ่งเหล่านี้ด้วยตนเอง ผมเคยใช้แหล่งข้อมูลนี้เป็นข้อมูลอ้างอิงในการทำว่าตนเองแปลง codepoints Unicode เข้า UTF-8 และ UTF-16 นี่เป็นบทสรุปสั้น ๆ เกี่ยวกับการแปลงอักขระ Unicode เป็น UTF-8:

  1. แปลงอักขระ Unicode เป็นค่า Unicode ของพวกเขา (เช่น"dЖ丽"จะกลายเป็น[100,1046,20029] )
  2. แปลงค่ายูนิโค้ดเหล่านี้เป็นไบนารี (เช่น[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 ไบต์
Neil

ข้อมูลจำเพาะอนุญาตให้เอาต์พุตอยู่ในรูปแบบที่สะดวกสบายใด ๆ เพื่อให้คุณสามารถเก็บไว้mapและปล่อยjoinให้อาร์เรย์ส่งออกบิต
Shaggy

60 ไบต์พร้อมเอาต์พุตเป็นอาร์เรย์ไบต์
Shaggy

ขอบคุณ @Neil และ @Shaggy !!
Luis felipe De jesus Munoz




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 .

ลองออนไลน์

คำอธิบาย:

:

  • var s มีสตริงโค้ดต้นฉบับที่ยังไม่ฟอร์แมต
  • %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 bytesใช้แลมบ์ดาเพราะแหล่งที่มาทั้งหมดเป็น ascii ดูเหมือนว่าc&255ไม่จำเป็นต้องใช้int ที่ไม่ได้ลงนาม
Nahuel Fouilleul

@NahuelFouilleul คำถามเดิมระบุไว้ว่า " คุณต้องสร้างโปรแกรมแบบเต็ม " และ " ผลลัพธ์ของคุณจะต้องพิมพ์ไปที่ STDOUT " ดังนั้นรหัสแผ่นส่วนขอบ verbose ที่ฉันมีแทนที่จะเป็นฟังก์ชัน lambda ที่ส่งคืนสตริง ข้อดีคือไม่ต้องใช้&255เพราะเราไม่ได้ใช้ตัวอักษรที่ไม่ใช่ ASCII ขอบคุณ!
Kevin Cruijssen

ตกลงฉันยังไม่ค่อยพอใจกับการใช้ภาษาอื่น ๆ แต่ภาษาอื่นเช่นจาวาสคริปต์ให้แลมบ์ดาส่งคืนสตริงและฉันก็ไม่เข้าใจว่าทำไมในจาวาเราไม่นับประเภทและเซมิโคลอนสุดท้ายเมื่อใช้แลมบ์ดา หากฎ?
Nahuel Fouilleul

1
นั่นคือสิ่งที่ฉันหลงทาง แต่ฉันพยายามและนี่เป็นผู้สมัครใหม่สำหรับ 184 ไบต์ บอกฉันว่าฉันทำผิดที่ไหนสักแห่ง;)
Olivier Grégoire

1
@ OlivierGrégoireอ่าเป็นวิธีที่ดี! ลืมBigIntegerเรื่องสั้นไปเลยอย่างสิ้นเชิงสำหรับการเปลี่ยนมาใช้ระบบเลขฐานสอง และ 2 ไบต์มากขึ้นโดยการเปลี่ยนreturn'0'+ไปreturn 0+ไปอืมทำไมจึงเป็นผู้นำที่0จำเป็น btw? มันสับสนผมว่าภายในไบนารี Strings ทั้งหมดมีชั้นนำนี้0แต่แรกอย่างใดอย่างหนึ่งไม่ได้เมื่อใช้BigInteger.toString(2)..
เควิน Cruijssen

2

Python 2 , 68 67 ไบต์

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

ลองออนไลน์!

การปรับเปลี่ยนของ คำตอบนี้

-1 ไบต์โดยการลบช่องว่างหลังจาก 'in' (ขอบคุณ @mdahmoune)


-1 ไบต์: คุณสามารถปล่อยพื้นที่หลังจากin
mdahmoune

คุณยังไม่ได้อัปเดตลิงค์ TIO นอกจากนี้ฉันพยายามที่จะทำ'%08b'%ord(i)แทนbin(256|ord(i))[3:]แต่มันไม่ทำงานด้วยเหตุผลบางอย่าง
Jo King

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

เครื่องมือทุบตี + GNU ขนาด 48 ไบต์

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

TIO


ขอบคุณปรับปรุงแน่นอนมันเป็นรูปแบบที่สั้นที่สุดมิฉะนั้นจะถูกลบออกจากการแสดงผลกับดัก
Nahuel Fouilleul
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.