เอาต์พุตต้นทางทีละบิต


18

เขียนโปรแกรมหรือฟังก์ชั่นที่ไม่ว่างเปล่าที่เมื่อเรียกว่าเอาท์พุทค่าเดียว, 1 หรือ 0, และเมื่อเรียกหลาย ๆ ครั้ง, หมายเลขเอาท์พุตจะสร้างการแสดงเลขฐานสองของซอร์สโค้ดของโปรแกรมของคุณ (ในหน้ารหัสเดียวกัน / ตีความ)

ตัวอย่างเช่นหากซอร์สโค้ดของคุณคือabc(ใน ASCII) ผลลัพธ์จะเป็น:

1st call:  0           // ASCII letter 'a'
2nd call:  1
3rd call:  1
4th call:  0
5th call:  0
6th call:  0
7th call:  0
8th call:  1

9th call:  0           // ASCII letter 'b'
10th call: 1
11th call: 1
12th call: 0
13th call: 0
14th call: 0
15th call: 1
16th call: 0

17th call: 0           // ASCII letter 'c'
18th call: 1
19th call: 1
20th call: 0
21st call: 0
22nd call: 0
23rd call: 1
24th call: 1

After the 24th call, the behaviour is undefined.

การเป็นตัวแทนไบนารีของแหล่งที่มาจะต้องมีอย่างน้อยหนึ่ง 0 บิตและหนึ่ง 1 บิต

แทนที่จะเป็น 1 และ 0 คุณสามารถส่งออกค่าที่ต่างกันสองค่าที่สอดคล้องกัน (เช่นtrueและfalse)

โปรแกรมที่แก้ไขด้วยตนเองที่อนุญาตให้แสดงไบนารีของแหล่งต้นฉบับอนุญาตได้โดยที่พวกเขาไม่ได้อ่านซอร์สโค้ดเพื่อค้นหาว่าจะพิมพ์อะไรต่อไป

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ

คำตอบ:


8

ฟังกี้ , 47 41 37 ไบต์

ส่งคืนตัวเลขที่แทนค่าบิต

f=_=>1&("%b"%("f="+f)[i//8])>>7-i++%8

f=_=>"f="+fนี้จะใช้รูปแบบของควิน ใช้อักขระที่ตำแหน่งati / 8⌋จากนั้นรับบิตโดยการจับคู่ของn >> 7-i%8ตำแหน่งที่nเป็นค่า ASCII ของอักขระปัจจุบัน

นี่เป็นฟังก์ชั่นวนซ้ำที่เพิ่มขึ้นiกับการโทรแต่ละครั้งเมื่อมันไม่อยู่ในซอร์สโค้ดมันจะเขียนโค้ดnไปตลอดกาล

ลองออนไลน์!


นี่เป็นหลายภาษาพร้อม JavaScript หรือไม่
Stan Strum

9

Bash , 105 ไบต์

trap -- 'trap|xxd -b -c1|cut -d\  -f2|tr -d \\n|cut -c`x=\`cat f||echo 1\`;echo $((x+1))>f;echo $x`' EXIT

หมายเหตุ : ตรวจสอบให้แน่ใจว่าคุณไม่มีไฟล์สำคัญที่เรียกว่าfในไดเรกทอรีที่คุณกำลังทดสอบนี้


หากคุณต้องการทดสอบสิ่งนี้คุณสามารถใช้คำสั่งต่อไปนี้:

for i in $(seq 848); do bash path/to/script.sh 2> /dev/null; done | tr -d \\n

xxd -c1 -b path/to/script.sh|cut -d\ -f2|tr -d \\nซึ่งจะให้ผลผลิตเดียวกัน

คำอธิบาย

นี่คือการใช้trapเคล็ดลับ - การเรียกใช้trapภายในการtrapดำเนินการเพียงพิมพ์บรรทัดนั้น ถัดไปว่าการส่งออกจะได้รับการประปาxxdซึ่งจะแปลงมันไบนารี (น่าเสียดายที่xxd -bpไม่ทำงาน - จึงแก้ปัญหาด้วยcut& tr):

xxd -c1 -b $0|cut -d\  -f2|tr -d \\n

จากที่เราสนใจเพียงหนึ่งบิต (พูดN) ซึ่งเราสามารถเลือกcut -cNได้

ในการค้นหาสิ่งที่Nเรากำลังใช้งาน (โปรดจำไว้ว่านั่นคือส่วนที่ต้องเพิ่มขึ้นหลังจากการโทรแต่ละครั้ง) เพียงลองตั้งค่าxเป็นเนื้อหาของไฟล์fและหากไม่มีอยู่ให้ตั้งค่าเป็น 1:

x=`cat f||echo 1`

สิ่งสุดท้ายที่ต้องทำคือการอัพเดตไฟล์f- เขียนx+1ลงไป:

echo $((x+1))>f

7

TI-Basic (TI-83 series), 592 357 309 ไบต์

"123456789ABCDEF02A3132333435363738394142434445463004AA003FB958833404593FB9588338045A3F3230363FDA582B383F303FCE5A405A6B3232333F5A70BB0FAA002BBB0CAA002B5A2B313FB932BA32F01058713459713511BB0FAA002BBB0CAA002B597031377132722B31→Str1
iPart(X/4→Y
iPart(X/8→Z
206
IS>(X,8
0
If Z and Z<223
Z+inString(Str1,sub(Str1,Z,1
iPart(2fPart(2^(X-4Y-5)inString(Str1,sub(Str1,Y+17-2Ans,1

ตารางนี้เป็นข้อมูลอ้างอิงที่เป็นไปได้สำหรับการแสดงเลขฐานสองของเครื่องคิดเลขของซอร์สโค้ด แต่ท้ายที่สุดฉันเพิ่งใช้ดีบักเกอร์ Virtual TI

สำหรับการเปรียบเทียบและ / หรือดอกเบี้ยประวัติศาสตร์: quines แรกที่เขียนใน TI-Basic

มันทำงานอย่างไร

Str1เก็บซอร์สโค้ด (ขณะนี้อยู่ในเลขฐานสิบหกอันรุ่งโรจน์ประหยัดพื้นที่จำนวนมากเหนือไบนารีเวอร์ชันก่อนหน้านี้) โดยปล่อยบิตที่เนื้อหาของStr1ตัวเองจะถูกนำเสนอ

เราสมมติว่าโปรแกรมจะเริ่มออกมาบนเครื่องคิดเลขที่มีหน่วยความจำที่ได้รับเพียงแค่ล้างเพื่อให้เป็นX 0ทุกครั้งที่มีโปรแกรมเราเพิ่มขึ้นXทุกครั้งที่ผ่านโปรแกรมที่เพิ่มขึ้นเรา

โดยปกติเราแค่คิดครึ่งไบต์ที่เราพยายามแยกออกมาอ่านจากStr1แปลงจากเลขฐานสิบหกเป็นเลขฐานสองแล้วพิมพ์ออกมา ถ้าเราอยู่ในส่วนหนึ่งของรหัสที่มาที่การจัดเก็บStr1(ซึ่งเป็นสองในสามของความยาวทั้งหมดของโปรแกรม) แล้วเราย้ายครั้งแรกที่จะเป็นส่วนหนึ่งที่สอดคล้องกันของการจัดเก็บสตริง31, 32และอื่น ๆ


4

Java 8, 249 241 237 234 148 ไบต์

int i;v->{String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}

ขออภัยล่วงหน้าสำหรับคำอธิบายที่ยาว :)

  • มหันต์ 89 ไบต์บันทึกขอบคุณที่@Nevay

ลองที่นี่

คำอธิบาย:

int i;                     // Index-integer on class-level
v->{                       // Method with empty unused parameter and integer return-type
  String s="int i;v->{String s=%c%s%1$c;return s.format(s,34,s).charAt(-i/8)>>(--i&7)&1;}";
                           //  String containing the unformatted source code
  return s.format(s,34,s)  //    Quine to get the source code,
      .charAt(-i/8)        //     and get the character at index `-i/8`
     >>                    //    And bitwise right-shift it with:
       (--i&7)             //     `i-1` bitwise-AND 7
                           //     by first decreasing `i` by 1 with `--i`
      &1;                  //   Then bitwise-AND everything above with 1
}                          // End of method

คำอธิบายเพิ่มเติม:

:

  • String s มีซอร์สโค้ดที่ยังไม่ฟอร์แมต
  • %s จะใช้ในการใส่สายนี้เป็นของตัวเองด้วย s.format(...)
  • %c, %1$cและ34จะใช้ในการจัดรูปแบบราคาสองครั้ง (" )
  • s.format(s,34,s) ทำให้มันเข้าด้วยกัน

ลองใช้ที่นี่ด้วยการลบ / แก้ไขบางส่วนเพื่อตรวจสอบผลลัพธ์ควินินซึ่งเป็นรหัสต้นฉบับของตัวเอง

ส่วน :


คำตอบเก่า233 ไบต์ :

int i;v->{String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%8);}

ลองที่นี่

คำอธิบาย:

int i;                           // Index-integer on class-level
v->{                             // Method with empty unused parameter and char return-type
  String s="int i;v->{String s=%c%s%1$c;return Long.toString((s.format(s,34,s).charAt(i/8)&255)+256,2).substring(1).charAt(i++%%8);}";
                                 //  String containing the unformatted source code
  return Long.toString(
          (s.format(s,32,s)      //  Quine-formatting
          .charAt(i/8)           //  Take the current character
           &255)+256,2).substring(1)
                                 //  Convert it to an 8-bit binary-String 
         .charAt(i++%8);         //  And return the bit at index `i` modulo-8
                                 //  and increase index `i` by 1 afterwards with `i++`
}                                // End of method

คำอธิบายเพิ่มเติม:

:

คำอธิบายเดียวกับข้างต้นด้วยการเพิ่ม:

  • %%เป็นรูปแบบการหลบหนีของ modulo-sign ( %)

ลองใช้ที่นี่ด้วยการลบ / แก้ไขบางส่วนเพื่อตรวจสอบผลลัพธ์ควินินซึ่งเป็นรหัสต้นฉบับของตัวเอง

ส่วน :

  • i/8จะตัดโดยอัตโนมัติในการหารจำนวนเต็มดังนั้นเมื่อiเป็น 0-7 มันจะกลายเป็น0; ถ้าiเป็น 8-15 มันจะกลายเป็น1 ; เป็นต้น
  • ดังนั้นs.charAt(i/8)ต้องใช้ตัวละครปัจจุบันของซอร์สโค้ดแปดครั้งต่อกัน ลองใช้ที่นี่พร้อมกับเวอร์ชันที่แก้ไข
  • 255คือ0xFFหรือ11111111(ค่าสูงสุดสำหรับไบต์ที่ไม่ได้ลงนาม)
  • 256 คือ 0x100100000000หรือ
  • &upcasts ASCII ที่ตัวอักษรเป็นจำนวนเต็ม ณ จุดนั้นมันอยู่ที่ใดก็ได้ระหว่าง0และ255( 00000000ถึง11111111 )
  • Long.toString(...,2) แปลงเป็นตัวแทนสตริงไบนารี 9 บิต
  • +256และ.substring(1)จะทำให้แน่ใจว่ามีเลขศูนย์นำหน้าและจะแปลง 9 บิตเป็น 8 บิต

ลองที่นี่ด้วยการลบ / แก้ไขบางส่วนเพื่อตรวจสอบไบต์ทั้งหมด


1
149 ไบต์:int i;v->{String s="int i;v->{String s=%c%s%1$c;return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}";return 1&s.format(s,34,s).charAt(-i/8)>>(--i&7);}
Nevay

@Nevay Whopping บันทึก 88 ไบต์ ขอบคุณ! และเนื่องจากที่จริงแล้วมันเป็นวิธีการที่แตกต่างจากเดิมเล็กน้อยฉันจึงเก็บคำตอบเก่าไว้และเพิ่มคำตอบใหม่ (ถ้าคุณต้องการฉันจะลบมันอีกครั้งและคุณสามารถโพสต์ด้วยตัวเอง แต่คุณบอกฉันในอดีตที่คุณต้องการเล่นกอล์ฟคนอื่น - ส่วนใหญ่เป็น XD ของฉัน - รหัสแทนที่จะโพสต์คำตอบของคุณเองใช่ไหม?)
Kevin Cruijssen

2

Javascript ES6, 73 58 52 ไบต์

o=_=>`o=${o}`.charCodeAt((o.n=1+o.n|0)/8)>>(7-o.n%8)&1

คำอธิบาย

รายละเอียดของรหัส:

  • o=_=>: กำหนดฟังก์ชั่น
  • `o=${o}`: สร้างสตริง; oถูกแปลงเป็นสตริงซึ่งในกรณีนี้คือซอร์สโค้ดของฟังก์ชัน
  • .charCodeAt(: รับอักขระในสตริงเป็นรหัสอักขระ ASCII
  • (o.n=1+o.n|0)/8: เลือกตัวละคร นี่เป็นที่ที่ตัวนับเพิ่มขึ้น
  • )>>(7-o.n%8): เลื่อนโค้ดอักขระที่ได้เพื่อให้บิตที่ต้องการอยู่ในตำแหน่งที่ถูกต้อง
  • &1: ตั้งค่าบิตอื่น ๆ ทั้งหมดเป็น 0

คุณสามารถย่อสิ่งนี้ด้วยแลมบ์ดาได้o=_=>(o+'').charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco

สิ่งนี้นับเป็นการนิยามฟังก์ชั่น
ATaco

1
ลองo=_=>('o='+o).charCodeAt(('n'in top?++n:n=0)/8|0)>>(7-n%8)&1
ATaco

แทนที่จะ'n'in top?++n:n=0ใช้++n||(n=0)หรือคุณสามารถ++n?n:n=0หรือn=++n||0หรือn=1+n||0ที่ทุกคนใช้ falsiness ของNaNที่ผลิตโดยการเพิ่มundefined
Bergi

1
o=_=>('o='+o).charCodeAt((o.n=1+o.n|0)/8)>>(~o.n&7)&1
tsh

2

q / kdb + , 45 ไบต์

วิธีการแก้:

a:-1;f:{((,/)0b vs'4h$"a:-1;f:",($).z.s)a+:1}

ตัวอย่าง:

q)f[] / call function f with no parameters
0b   
q)f[]
1b   
q)f[]
1b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
0b   
q)f[]
1b   
q)f[]  
q)"c"$0b sv 01100001b / join back to a byte and cast to a character
"a"

คำอธิบาย:

ฉันคิดว่าฉันเข้าใจสั้น ๆ

การติดตั้งครั้งแรกตัวแปรทั่วโลกที่มีค่าเริ่มต้นของa -1ฟังก์ชั่นfสร้างการเป็นตัวแทนไบนารีของเป็นตัวแทนสตริงของฟังก์ชั่น (ทุกอย่างรวมถึง{}) ที่เติมด้วยa:-1;f:ขยะและดัชนีลงในรายการไบนารีนี้ที่ดัชนี a (ซึ่งได้รับเพิ่มขึ้นแต่ละสาย)

a:-1;f:{(raze 0b vs'4h$"a:-1;f:",string .z.s)a+:1} / ungolfed solution
a:-1;                                              / stick -1 in variable a
     f:{                                         } / define function f
                                             a+:1  / increment a by 1 (:: is required as a is a global variable), indexes into the left
        (                                   )      / do all this together
                                 string .z.s       / z.s is the function, string converts it to a string
                       "a:-1;f:",                  / prepend "a:-1;f:" to the start
                    4h$                            / cast to bytes
              0b vs'                               / convert each byte to binary
         raze                                      / flatten binary into long list

2

Python 2 , 164 ไบต์

lambda s='lambda s=%r,i=[]:i.append(1)or"{:08b}".format(ord((s%%s)[~-len(i)/8]))[~-len(i)%%8]',i=[]:i.append(1)or"{:08b}".format(ord((s%s)[~-len(i)/8]))[~-len(i)%8]

ลองออนไลน์!

คำอธิบาย

เริ่มจาก Python 2 quine มาตรฐานกันก่อน

s = '...'; print s % s

โอเคเอาท์พุทมันแบบนี้ เราต้องการไบนารี่!

s = '...'; print "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

ใช่แล้วมันจะแปลงทุกอย่างให้เป็นไบนารี่ แต่ชื่อบอกว่า "ทีละนิด" เราต้องการบางสิ่งบางอย่างเพื่อคงอยู่ผ่านการวิ่งหลายครั้ง ฉันรู้ว่ามาทำฟังก์ชั่นกันเถอะ!

lambda s = '...': "\n".join("\n".join("{:08b}".format(ord(i))) for i in s % s)

เดี๋ยวก่อนนั่นไม่ช่วยอะไรเลยอืมเราจะติดตามดัชนีของบิตที่ต้องใช้ในการส่งออกได้อย่างไร Ooh, ooh มามีจำนวนเต็มติดตามกัน

lambda s = '...', i = 0: "{:08b}".format(ord((s % s)[i / 8]))[i % 8]

อืม ... มันออกบิตแรกเสมอ โอ้เราต้องเพิ่มตัวติดตาม! โอ้อึ Python ไม่อนุญาตให้จำนวนเต็มเป็นอาร์กิวเมนต์เริ่มต้นที่จะแก้ไข และการมอบหมายไม่ใช่การแสดงออกใน Python ดังนั้นคุณไม่สามารถทำได้ในแลมบ์ดา ยินดีด้วยนี่เป็นไปไม่ได้ใน Python ปิดกรณี

... ไม่เลย งูหลามไม่อนุญาตให้รายการเป็นข้อโต้แย้งเริ่มต้นที่จะแก้ไข (และมันก็เขียนโปรแกรม Python ตลอดเวลา) มาลองใช้ความยาวของมันกันเถอะ!

lambda s = '...', i = []: "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

นั่นยังไม่ปรับเปลี่ยนตัวติดตามแม้ว่า ... เราสามารถต่อท้ายเพื่อเพิ่มความยาว ... แต่อย่างไร อ่าเรามีlist.appendแล้ว เทียบเท่ากับlst.append(1) lst += [1]ที่ดี!

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[len(i) / 8]))[len(i) % 8]

อ๊ะนี่จะข้ามบิตแรกเพราะความยาวของตัวติดตามคือ1ก่อนที่จะส่งออกบิต เราจำเป็นต้องลดความยาวที่ใช้

lambda s = '...', i = []: i.append(1) and "{:08b}".format(ord((s % s)[(len(i) - 1) / 8]))[(len(i) - 1) % 8]

นั่นคือคน! เล่นกอล์ฟแล้วคุณจะได้ทางออกของฉัน!


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