Quines เชิงลบร่วมกัน


22

สิ่งนี้ได้รับแรงบันดาลใจจากปรินท์การลบประมวลกฎหมายและกอล์ฟของคุณ


พิจารณาสี่เหลี่ยมผืนผ้าของอักขระที่ตรงตามข้อ จำกัด ต่อไปนี้:

  1. ประกอบด้วยอักขระ ASCII ที่พิมพ์ได้เท่านั้น
  2. ขนาดทั้งใหญ่กว่า 1
  3. แต่ละแถวและแต่ละคอลัมน์มีช่องว่างอย่างน้อยหนึ่งช่อง
  4. แต่ละแถวและแต่ละคอลัมน์มีอักขระที่ไม่ใช่ช่องว่างอย่างน้อยหนึ่งตัว

ตัวอย่างเช่นต่อไปนี้เป็นสี่เหลี่ยมผืนผ้า 6x4 ที่ถูกต้อง:

%n 2e 
1  g 3
 &* __
 3  

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

  f  ^
 33 > 
9  $  
^ }|Q'

อักขระ ASCII ที่ไม่สามารถพิมพ์ได้ใด ๆ ที่ไม่ใช่ช่องว่างอาจถูกใช้เพื่อแทนที่ช่องว่าง

งาน

งานของคุณคือการเขียนโปรแกรมด้วยซอร์สโค้ดรูปสี่เหลี่ยมผืนผ้าซึ่งให้ผลลบที่ถูกต้องกับตัวมันเอง ผลลัพธ์เชิงลบจะต้องเป็นโปรแกรมที่ถูกต้องในภาษาเดียวกันกับต้นฉบับและจะต้องส่งออกแหล่งที่มาของต้นฉบับ

ไม่มีช่องว่างต่อท้ายที่อาจจะเพิ่มหรือลบยกเว้นบรรทัดใหม่ต่อท้ายเดียวในตอนท้ายของการส่งออกอย่างใดอย่างหนึ่งซึ่งเป็นตัวเลือก

โปรแกรมไม่ได้รับอนุญาตให้อ่านซอร์สโค้ดของทั้งคู่ และไม่อาจถือว่าสภาพแวดล้อม REPL

เกณฑ์การให้คะแนน

คะแนนของคุณคือผลคูณของรหัสของคุณ (เช่นถ้าซอร์สโค้ดของคุณอยู่ในสี่เหลี่ยม 12 คูณ 25 คะแนนของคุณคือ 12 * 15 = 180) นอกจากนี้สำหรับตัวละครแต่ละตัวที่ใช้ในความคิดเห็นคะแนนของคุณจะเพิ่มขึ้น 2 (ถ้าคุณใช้/* .. */หนึ่งครั้งในรหัสของคุณและรหัสของคุณอยู่ในกรอบสี่เหลี่ยม 10 ถึง 10 คะแนนของคุณจะเท่ากับ 10 * 10 + 8 * 2 = 116)

คะแนนต่ำสุดชนะ

หากมีการเสมอกันการส่งที่มีจำนวนช่องว่างน้อยที่สุดในโปรแกรม (ไม่ว่าจะเป็นแบบดั้งเดิมหรือแบบลบ

หากยังคงมีเสมอคำตอบก่อนหน้านี้จะชนะ

มีโบนัส-52%หากรวมต้นฉบับและลบเข้าด้วยกันจะสร้างควินปกติ ตัวอย่างเช่น:

Original   Negative   Combined
 A A       B B        BABA
A A         B B       ABAB

@Optimizer นั่นเป็นเหตุผลที่ฉันไม่ได้ทำโบนัส
es1024

1
ฉันกำลังพูดถึงส่วนที่เป็นลบร่วมซึ่งเป็นลบ;)
เครื่องมือเพิ่มประสิทธิภาพ

@ MartinBüttnerอ่าฉันแย่มาก ฉันคิดในแง่แปลก ๆ
เครื่องมือเพิ่มประสิทธิภาพ

1
ใครสามารถทำสิ่งนี้ในค +1 กับใครก็ตามที่จะเป็นคนแรก!
MegaTom

คำตอบ:


15

CJam, ( 51 49 47 46 45 42 x 2) * 48% = 40.32

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

การเรียกใช้โค้ดด้านบนให้ผลลัพธ์นี้:

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

ทำงานซึ่งจะพิมพ์กลับมาต้นฉบับ

แหล่งที่มาและการส่งออกเป็นเพียงแค่การสลับบรรทัด

ตอนนี้ความมหัศจรรย์มา

การทับซ้อนแหล่งที่มาและผลลัพธ์ผลลัพธ์เป็นรหัสต่อไปนี้:

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

ซึ่งเป็น quine ที่สมบูรณ์แบบ!

ลองออนไลน์ได้ที่นี่


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

ตรรกะการพิมพ์ทั้งหมดอยู่ในบรรทัดแรกซึ่งรองรับทั้งสามกรณีที่อธิบายในภายหลัง

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~
{                                     }_~   "Copy this code block and execute the copy";
 ]                                          "Wrap everything before it in array";
  )                                         "Pop the last element out of it";
   "_~"+                                    "Append string '_~' to the copied code block";
        S41*                                "Create a string of 41 spaces";
            'R+                             "Append character R to it";
               @,                           "Rotate the array to top and get its length";
                 [{   }{   }{     }]=~      "Get the corresponding element from this"
                                            "array and execute it";

อาร์เรย์ในบรรทัดสุดท้ายด้านบนเป็นอาร์เรย์ที่มีบล็อกรหัสที่สอดคล้องกับทั้งสามกรณี

กรณีที่ 1

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 
                                         R

ในกรณีนี้ความยาวของสแต็กที่เหลือคือ 0 เหมือนกับเมื่อบล็อกถูกดำเนินการมันมีเพียงสำเนาของบล็อกเองซึ่งถูกเปิดออกในขั้นตอนที่สามด้านบนในขั้นต้น ดังนั้นเราจึงนำดัชนี0ออกจากอาร์เรย์สุดท้ายและดำเนินการ:

 {N@S}          "Note that at this point, the stack is something like:"
                "[[<code block that was copied> '_ '~ ] <41 spaces and R string>]";
  N             "Add newline to stack";
   @            "Rotate the code block to top of stack";
    S           "Put a trailing space which negates the original R";

ในกรณีนี้บรรทัดที่สองคือไม่มีการพิมพ์เท่าที่เกี่ยวข้องกับการพิมพ์เอาต์พุต

กรณีที่ 2

                                         R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~ 

ในกรณีนี้สแต็กมีสตริงว่างอยู่แล้วดังนั้นเมื่อมีการดำเนินการบล็อกโค้ดที่คัดลอกมันมีองค์ประกอบ 2 องค์ประกอบคือสตริงว่างและโค้ดบล็อกเอง ดังนั้นเราจึงนำดัชนี1ออกจากอาร์เรย์สุดท้ายและดำเนินการ:

{SN@}            "Note at this point, the stack is same as in case 1";
 SN              "Push space and newline to stack";
   @             "Rotate last three elements to bring the 41 spaces and R string to top";

กรณีที่ 3

{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R
{])"_~"+S41*'R+@,[{N@S}{SN@}{W=N]_}]=~}_~R

ในกรณีนี้สแต็กมี 6 องค์ประกอบ ดังนั้นหลังจาก popping บล็อกโค้ดสุดท้ายความยาวอาร์เรย์ที่เหลืออยู่คือ 5 เรานำดัชนี5ออกจากอาร์เรย์และดำเนินการ (โปรดทราบว่าในอาร์เรย์ของ3องค์ประกอบดัชนี5คือดัชนี5%3 = 2)

{W=N]_}          "Note at this point, the stack is same as in case 1";
 W=              "Take the last character out of the 41 spaces and R string, i.e. R";
   N]            "Add a new line to stack and wrap the stack in an array";
     _           "Copy the array to get back the source of Case 3 itself";

27

Python, 97x2 + 2 = 196

ไม่ใช่ทางออกที่ดีในการเริ่มต้น แต่อย่างน้อยก็ใช้งานได้ (ฉันคิดว่า)

c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%1) 
                                                                                                #

เอาท์พุท:

                                                                                                #
c='o=1-%d;print("%%97s\\n%%97s"%%("#","c=%%r;exec(c%%%%%%d)\\40"%%(c,o),"#")[o:][:2])';exec(c%0) 

8
+1 สำหรับการส่งเท่านั้นจนถึงการใช้ภาษาจริง
WinnieNicklaus

ดูเหมือนจะไม่ไกลเกินไปจากโบนัสเช่นกัน
mbomb007

23

CJam, ( 58 56 54 48 46 x 2) * 48% = 44.16

{`"_~"+{_,94\m2/S*a_+\*                       
                       N/23f/Wf%N*}_`'"#)!*}_~

ซึ่งพิมพ์

                       {`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~                       

อักขระที่ไม่ใช่ช่องว่างในแต่ละบรรทัดจะยังคงเหมือนเดิมระหว่างสอง quines ร่วมกัน

แต่ตอนนี้เป็นส่วนที่หวานจริงๆ:

{`"_~"+{_,94\m2/S*a_+\*{`"_~"+{_,94\m2/S*a_+\*
N/23f/Wf%N*}_`'"#)!*}_~N/23f/Wf%N*}_`'"#)!*}_~

เป็นควิน! :)

ทดสอบที่นี่

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

ฉันขอแนะนำให้คุณอ่านคำอธิบายเกี่ยวกับการส่งอื่น ๆ ของฉันก่อนเพราะอธิบายพื้นฐานของการเขียนข้อความใน CJam โดยทั่วไป

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

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

เพื่อให้ได้ควินปกติเมื่อรวมเข้าด้วยกันเราต้องหาวิธีที่จะหลีกเลี่ยงการแก้ไขทั้งหมด โปรดสังเกตว่าโครงสร้างของช่องว่างและรหัสหมายความว่าเมื่อรวมทั้งสองอย่างเข้าด้วยกันเราจะแทรกทั้ง quine หนึ่งเข้าไปในอีก quine ดังนั้นหากเราใส่รหัสการปรับเปลี่ยนทั้งหมดลงในบล็อกเราสามารถเรียกใช้บล็อกนั้นขึ้นอยู่กับเนื้อหาจริง

ดังนั้นตอนนี้ฉันมีบล็อกนี้ ... สำหรับ quines ร่วมมันมีเฉพาะรหัสที่ฉันต้องการเรียกใช้จริง ๆ สำหรับ quine ที่รวมกันมันยังมี quine ทั้งหมดอีกครั้งในตำแหน่งสุ่มซึ่งไม่สมเหตุสมผลใด ๆ ... แต่เนื่องจากเป็นบล็อกจึงไม่ทำงานโดยอัตโนมัติ ดังนั้นเราสามารถตรวจสอบว่าจะแก้ไขสตริงตามเนื้อหาของบล็อกนั้นหรือไม่ นั่นคือสิ่งที่_`'"#)!มีไว้เพื่อ มันทำซ้ำบล็อกแปลงเป็นสตริงค้นหาอักขระ"(ซึ่งใน quines ร่วมกันจะปรากฏเฉพาะนอกบล็อก) - การค้นหาส่งคืน-1หากไม่พบอักขระและจำนวนเต็มบวก - เพิ่มผลลัพธ์ และปฏิเสธมันอย่างมีเหตุมีผล ดังนั้นหาก"พบว่าสิ่งนี้ให้ผลเป็น0อย่างอื่น1มิฉะนั้นอัตราผลตอบแทนตอนนี้เราแค่ทำ*ซึ่งจะดำเนินการบล็อกครั้งเดียวหากผลลัพธ์เป็น 1 และไม่เป็นอย่างอื่น

ในที่สุดนี่คือวิธีการปรับเปลี่ยนรหัสการทำงาน:

_,94\m2/S*a_+\*N/23f/Wf%N*
_,                         "Duplicate the quine string and get its length.";
  94\m                     "Subtract from 94.";
      2/                   "Divide by two.";
        S*                 "Create a string with that many spaces. This will be
                            an empty string for the first mutual quine, and contain
                            23 spaces for the second mutual quine.";
          a_+              "Create an array that contains this string twice.";
             \*            "Join the two copies together with the quine string.";
               N/          "Split into lines.";
                 23f/      "Split each line into halves (23 bytes each).";
                     Wf%   "Reverse the two halves of each line.";
                        N* "Join with a newline.";

รับเงินรางวัล (12 x 10) * 48% = 57.6

ปรากฎว่ารหัสนี้สามารถแบ่งมากกว่าบรรทัดได้ง่ายขึ้นด้วยการแก้ไขบางอย่าง เราเพิ่ม 2 ตัวอักษรเพื่อให้ได้ 48 แถวติดต่อกันซึ่งเราสามารถหารด้วย 8 ได้อย่างสะดวกดังนั้นเราจึงมี 8 บรรทัดพร้อมรหัส 6 ตัวและ 6 ช่องว่าง ในการทำเช่นนั้นเราต้องเปลี่ยนตัวเลขสองสามตัวและจัดเรียงตัวดำเนินการใหม่หรือสองตัวดังนั้นพวกเขาจึงไม่แยกทั้งสองบรรทัด นั่นทำให้เรามีเวอร์ชั่นใช้งานด้วยขนาด12 x 8 ... อีกหนึ่งความต้องการ ดังนั้นเราแค่เพิ่มสองบรรทัดที่ไม่ทำอะไรเลย (กด 1, กด 1, กด 1, กด 1, เลื่อน 1 ... ), ไปที่12 x 10 :

{`"_~"      
      +{129X
$,m2/S      
      *a_+\*
N/6f/1      
      ;1;1;1
;1;1;1      
      ;Wf%N*
}_`'"#      
      )!*}_~

เช่นเดียวกับก่อนหน้านี้ผลิต

      {`"_~"
+{129X      
      $,m2/S
*a_+\*      
      N/6f/1
;1;1;1      
      ;1;1;1
;Wf%N*      
      }_`'"#
)!*}_~      

(หมายเหตุด้าน: ไม่จำเป็นต้องสลับซ้ายและขวาบนเส้นกลางเพียงตำแหน่งของบรรทัดแรกและบรรทัดสุดท้ายเท่านั้นที่มีความสำคัญคุณสามารถเลือกซ้ายและขวาได้โดยอิสระสำหรับบรรทัดอื่น ๆ )

และด้วยความบังเอิญที่บริสุทธิ์ควินเต็มก็ยังใช้งานได้:

{`"_~"{`"_~"
+{129X+{129X
$,m2/S$,m2/S
*a_+\**a_+\*
N/6f/1N/6f/1
;1;1;1;1;1;1
;1;1;1;1;1;1
;Wf%N*;Wf%N*
}_`'"#}_`'"#      
)!*}_~)!*}_~

(ฉันบอกว่าบังเอิญเพราะส่วนที่ดูแลไม่ดำเนินการโค้ดภายในตอนนี้ได้รับการสลับกับควินอื่น ๆ แปลก ๆ แต่มันก็ยังเกิดขึ้นในการทำงานได้ดี)

ที่ถูกกล่าวว่าฉันจะได้เพิ่ม 44 บรรทัดของ1;การส่งต้นฉบับของฉันเพื่อตอบสนองความต้องการความโปรดปราน แต่12 x 10ดู neater มาก ;)

แก้ไข:ฮ่าฮ่าเมื่อฉันพูดว่า "บังเอิญแท้ๆ" ฉันไม่สามารถทำอะไรได้มากกว่านี้ ฉันดูว่าตอนนี้ควินินสุดท้ายใช้งานได้จริงอย่างไรและมันไร้สาระอย่างแน่นอน มีสามบล็อกซ้อนกัน (4 อันที่จริงแล้ว แต่ส่วนในสุดนั้นไม่เกี่ยวข้อง) ส่วนที่สำคัญที่สุดของส่วนท้ายสุดของบล็อกทั้งสามนั้นคือมันมี"(และไม่ใช่ส่วนที่อยู่ในการส่งดั้งเดิม แต่ส่วนมาก'"ที่ใช้ในตอนท้ายเพื่อตรวจสอบอักขระเดียวกันนี้) ดังนั้นโครงสร้างพื้นฐานของควินคือ:

{`"_~"{`"_~"+{___'"___}_`'"#)!*}_~)!*}_~

ลองผ่าว่า:

{`"_~"                               }_~ "The standard CJam quine.";
      {`"_~"+                  }_~       "Another CJam quine. Provided it doesn't do 
                                          anything in the rest of that block, this 
                                          will leave this inner block as a string on 
                                          the stack.";
                                  )      "Slice the last character off the string.";
                                   !     "Negate... this yields 0.";
                                    *    "Repeat the string zero times.";

ดังนั้นสิ่งนี้จึงทำเวทมนตร์ตลก ๆ แต่เนื่องจากบล็อกด้านในออกจากสายอักขระเดียวบนสแต็กจึง)!*เกิดเป็นสายอักขระว่างเปล่า เงื่อนไขเดียวคือสิ่งของในบล็อกด้านในหลังจาก+ไม่ได้ทำอะไรกับสแต็คดังนั้นให้ดูที่:

             {___'"___}                  "Push a block which happens to contain 
                                          quotes.";
                       _`'"#)!*          "This is from the original code and just 
                                          removes the block if it does contain 
                                          quotes.";


ไม่ควรอยู่Y/2ในการรวมควินหรือไม่
schnaader

"และผ่านความบังเอิญที่บริสุทธิ์" nah;)
Timtech

@Timtech ดูการแก้ไขของฉัน ความบังเอิญที่บริสุทธิ์ไม่ใช่การพูดเกินจริง ^^
Martin Ender

10

CJam, 42 37 33 x 2 = 66

{`As_W%er"_~"+S 33*F'Lt1{\}*N\}_~
               L                 

ซึ่งพิมพ์

               L                 
{`As_W%er"_~"+S 33*F'Lt0{\}*N\}_~

(เส้นถูกเปลี่ยนและ1กลายเป็น a 0.)

ทดสอบที่นี่

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

ขั้นแรกคุณควรเข้าใจพื้นฐานของ CJam:

{"_~"}_~

เครื่องมือจัดฟันจะกำหนดกลุ่มของรหัสเช่นฟังก์ชันที่ไม่ได้ดำเนินการในทันที หากบล็อกที่ไม่ได้ดำเนินการยังคงอยู่ในสแต็กรหัสแหล่งที่มา (รวมถึงวงเล็บปีกกา) จะถูกพิมพ์ _ทำซ้ำบล็อกและ~ดำเนินการสำเนาที่สอง _~บล็อกตัวเองเพียงแค่ผลักดันสตริงที่มี ดังนั้นรหัสนี้ปล่อยให้กองอยู่ในสถานะต่อไปนี้:

Stack: [{"_~"} "_~"]

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

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

ทีนี้ลองดูวิธีแก้ปัญหานี้ ขอให้สังเกตว่าเป็นส่วนหนึ่งของควินร่วมกันอย่างใดอย่างหนึ่งมีของบล็อกควินเช่นเดียวกับและ_~ ผลักดันให้เป็นสตริงว่างลงบนสแต็คซึ่งไม่ได้มีส่วนร่วมในการส่งออก ดังนั้นนี่คือสิ่งที่บล็อกทำ:LL

`                             "Convert block to its string representation.";
 As                           "Push 10 and convert to string.";
   _W%                        "Duplicate and reverse, to get another string 01.";
      er                      "Swap 0s and 1s in the block string.";
        "_~"+                 "Append _~.";
             S 33*            "Push a string with 33 spaces.";
                  F'Lt        "Set the character at index 15 to L.";
                      1{ }*   "Repeat this block once.";
                        \     "Swap the code string and the space string.";
                           N\ "Push a newline and move it between the two lines.";

ดังนั้นสิ่งนี้จะทำส่วนควินิน แต่แลกเปลี่ยน 1 สำหรับ 0 และมันยังจะเสริมสายอื่นด้วยการLที่รหัสข้างต้นมีช่องว่าง { }*จับเป็นว่าคำสั่งของทั้งสองสายจะถูกกำหนดโดยภายในการแลกเปลี่ยน และเนื่องจากส่วนนอกของ quine ร่วมมี0ด้านหน้าแทนที่ด้วย a 1จึงไม่ดำเนินการแลกเปลี่ยนนี้ดังนั้นจึงสร้างคำสั่งเดิมอีกครั้ง


5

CJam, 27 × 2 = 54

{ ` " _ ~ " + N - ) 2 * ' '
 > @ t s G B + / N * } _ ~ 

เอาท์พุท:

 { ` " _ ~ " + N - ) 2 * ' 
' > @ t s G B + / N * } _ ~

'A'B>เปรียบเทียบอักขระ A และ B ' '\n >ส่งคืน 1 เนื่องจาก 32> 10 และ' \n' >ส่งกลับ 0 เนื่องจากช่องว่างสองช่องเท่ากัน


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