เครื่องกำเนิด Quine ทั่วไป


19

ความท้าทาย

ในความท้าทายนี้คุณระบุภาษาต้นฉบับ Sและภาษาเป้าหมาย Tงานของคุณคือการเขียนโปรแกรมดังต่อไปนี้ในภาษาที่P Sถ้าเป็นโปรแกรมที่ถูกต้องQในภาษาที่Tจะได้รับเป็น input เพื่อPมันจะได้ผลลัพธ์เป็นโปรแกรมที่ถูกต้องRในภาษาที่Tซึ่งจะเข้าไม่ได้และเอาท์พุทQ(R)ที่เป็นโปรแกรมที่นำไปใช้กับรหัสที่มาของQ นอกจากนี้คุณควรจะนำเสนอในคำตอบของคุณโปรแกรมตัวอย่างขี้ปะติ๋ว(น่าสนใจมากขึ้นดีกว่าแม้ว่าคุณแต้มสำหรับเรื่องนี้) โปรแกรมส่งผลและการส่งออกของ นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดสำหรับการชนะRQRRP

กล่าวอีกนัยหนึ่งนี่เป็นความท้าทายเกี่ยวกับการเขียน "ตัวสร้างควินสากล" ซึ่งสามารถสร้างประเภททั่วไปได้ตามอำเภอใจ

ชี้แจง

  • ภาษาต้นทางและเป้าหมายของคุณอาจเหมือนกัน
  • โปรแกรมที่Pควรใช้เวลาหนึ่งสตริงเป็น input (จาก STDIN หรือเทียบเท่า) และสตริงหนึ่ง output (เพื่อ STDOUT หรือเทียบเท่า) Rเป็นโปรแกรมควรส่งออกทุก
  • โปรแกรมอินพุตQควรแปลงสตริงเป็นสตริงอื่น แต่รูปแบบมีความยืดหยุ่นมากขึ้น: สามารถเป็นฟังก์ชั่นแบบสตริงต่อสตริง, โค้ดขนาดเล็กที่ปรับเปลี่ยนตัวแปรด้วยชื่อที่แน่นอน, สนิปเพตที่ปรับเปลี่ยนสแต็คข้อมูลหากภาษาเป้าหมายของคุณ มีหนึ่งรายการและอื่น ๆ คุณสามารถ จำกัด รูปแบบของรายการเพิ่มเติมQโดยระบุว่าตัวอย่างเช่นพวกเขาอาจไม่มีความคิดเห็นใด ๆ อย่างไรก็ตามคุณต้องสามารถใช้ฟังก์ชัน string-to-string ที่คำนวณได้ใด ๆ เป็นโปรแกรมอินพุตQและคุณต้องระบุอย่างชัดเจนถึงวิธีการทำงานของฟังก์ชันและข้อ จำกัด เพิ่มเติมที่คุณมีต่อฟังก์ชันเหล่านั้น
  • โปรแกรมเอาต์พุตRควรเป็น quine (ทั่วไป) ดังนั้นจึงต้องไม่อ่านอินพุตใด ๆ (อินพุตของผู้ใช้ไฟล์ ฯลฯ ) เว้นแต่Qจะเป็นเช่นนั้น
  • ช่องโหว่มาตรฐานไม่ได้รับอนุญาต

ตัวอย่าง

สมมติว่าฉันเลือก Python เป็นภาษาต้นฉบับของฉันและ Haskell เป็นภาษาเป้าหมายของฉันและฉันต้องต่อว่าโปรแกรมการป้อนข้อมูลที่ควรจะเป็นความหมายหนึ่งบรรทัดของฟังก์ชั่นการตั้งชื่อString -> String fถ้าฉันให้โปรแกรมย้อนกลับสตริง

f x = reverse x

เป็นข้อมูลในการเขียนโปรแกรมหลามของฉันก็จะออกรหัสที่มาของโปรแกรมP Haskell อื่น Rโปรแกรมนี้พิมพ์ไปที่ STDOUT ซอร์สโค้ดของRแต่กลับด้าน หากPได้รับฟังก์ชั่นตัวตน

f x = x

เป็นอินพุตโปรแกรมเอาต์พุตRเป็น quine

คำตอบ:


7

แหล่งที่มา = เป้าหมาย = CJam, 19 17 16 ไบต์

{`"_~"+}`)q\"_~"

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

ทดสอบที่นี่

ตัวอย่าง

  1. ข้อมูลระบุตัวตนจะเป็นข้อมูลโค้ดที่ว่างเปล่าดังนั้นให้ปล่อยให้พิมพ์ STDIN ว่างเปล่า

    {`"_~"+}_~
    

    +ซึ่งเป็นควินมาตรฐานเพิ่มเติมด้วย

  2. ในการย้อนกลับสตริงใน CJam คุณสามารถใช้W%ดังนั้นวางบน STDIN ผลตอบแทนนี้:

    {`"_~"+W%}_~
    

    ซึ่งเราสามารถเรียกใช้เพื่อขอรับ

    ~_}%W+"~_"`{
    
  3. ในฐานะที่เป็นตัวอย่างที่สามกล่าวว่าเราจะใช้ข้อมูลโค้ดซึ่ง intersperses ' *สตริงที่มีช่องว่างที่: ทำงานPด้วยสิ่งนั้นในฐานะอินพุตเราจะได้รับ

    {`"_~"+' *}_~
    

    ซึ่งจะพิมพ์

    { ` " _ ~ " + '   * } _ ~  
    
  4. ตอนนี้ยังใช้งานได้หากQมีตัวแบ่งบรรทัด (แม้ว่าจะไม่จำเป็นใน CJam) นี่คือโปรแกรมที่มีตัวแบ่งบรรทัดซึ่งลบตัวแบ่งบรรทัดทั้งหมดออกจากสตริง (ในลักษณะที่ซับซ้อนโดยไม่จำเป็น - แบ่งออกเป็นบรรทัดแล้วเข้าร่วม):

    N/
    ""
    *
    

    ผลลัพธ์นี้ในต่อไปนี้R:

    {`"_~"+N/
    ""
    *}_~
    

    ซึ่งจะพิมพ์

    {`"_~"+N/""*}_~
    

คำอธิบาย

ลองดูผลลัพธ์ที่ผลิตออกมาก่อน:

มาตรฐาน CJam คือ

{`"_~"}_~

มันทำงานได้ดังต่อไปนี้:

  • {`"_~"}ผลักดันบล็อก
  • _ซ้ำด้วย
  • ~ดำเนินการคัดลอกด้วย
  • ตอนนี้ภายในบล็อก`เปลี่ยนบล็อกแรกเป็นการแสดงสตริง
  • "_~" ดันอักขระสองตัวของซอร์สที่ไม่ได้เป็นส่วนหนึ่งของบล็อก (และหายไปจากการแสดงสตริง)
  • สตริงทั้งสองจะถูกพิมพ์กลับไปด้านหลังในตอนท้ายของโปรแกรม

ในพื้นฐาน quine `นั้นไม่จำเป็นเพราะถ้าคุณเพิ่งออกจากบล็อกมันเป็นมันจะพิมพ์เหมือนกันทั้งหมดในตอนท้ายของโปรแกรม

ผลลัพธ์ของโปรแกรมของฉันPเป็นตัวอย่างที่แก้ไขแล้ว ก่อนอื่นฉันได้เพิ่ม a +ลงในบล็อกซึ่งเชื่อมสองสายเข้าด้วยกันเป็นหนึ่งสายที่มีทั้งซอร์ส `หมายเหตุที่ว่านี้จะเป็นจริงไม่ว่าสิ่งที่ฉันทำภายในบล็อกเนื่องจากว่าทั้งหมดจะได้รับการบันทึกการแสดงสตริงที่ได้รับด้วย ตอนนี้ฉันสามารถวางโปรแกรม / ตัวอย่างQไว้ในบล็อกหลัง+เพื่อที่จะสามารถแก้ไขสตริงต้นฉบับก่อนที่จะพิมพ์ อีกครั้งเนื่องจากQเข้าไปในบล็อกมันจะเป็นส่วนหนึ่งของสตริงที่กล่าวมา

โดยสรุปPพิมพ์

{`"_~"+Q}_~

ตอนนี้สำหรับวิธีที่ฉันไปเกี่ยวกับการสร้างผลลัพธ์นี้ในP:

{`"_~"+}         "Push the block without Q.";
        `        "Turn it into a string. This is shorter than writing a string right away,
                  because I'd have to escape the quotes, and I'd need two quotes instead of
                  one backtick.";
         )       "Pop off the last character (the brace) and push it on the stack.";
          q      "Read input Q.";
           \     "Swap Q with the brace.";
            "_~" "Push the final two characters.";

สตริงที่สี่จะถูกพิมพ์โดยอัตโนมัติ (back-to-back) ที่ส่วนท้ายของโปรแกรม


1
นี่มันเร็วมาก! และยากที่จะเอาชนะอย่างแน่นอน คำอธิบายก็ดีเช่นกัน
Zgarb

คุณเรียนรู้ว่า W% กลับด้านที่ไหน dl.dropboxusercontent.com/u/15495351/cjam.pdfไม่มี
Faraz Masroor

มีรายการวิธีการที่สมบูรณ์กว่านี้ไหม?
Faraz Masroor

@FarazMasroor sourceforge.net/p/cjam/wiki/Basic%20operators/#percent (หมายเลข 3) ... เป็นคุณลักษณะที่ยืมมาจาก GolfScript และในบางครั้งมีคนบอกฉันว่ามันทำงานอย่างไรใน GolfScript ดูเหมือนจะเป็นสำนวนสามัญที่มีความรู้โดยนัยแปลก ๆ ที่ผู้ใช้ CJam / GS ทุกคนมี แต่ที่ไม่ได้อธิบายจริงในสถานที่จำนวนมาก (สำหรับตัวดำเนินการเพิ่มเติมที่ไม่ได้บันทึกไว้อย่างละเอียดให้ดูsourceforge.net/p/cjam/wiki/Operators )
Martin Ender

3

นิพจน์ Haskell →นิพจน์ Haskell, 41 ไบต์

((++)<*>show).('(':).(++")$(++)<*>show$")

ลองออนไลน์!

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

P $ "Q"= ((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"สร้าง"R"โดย

  1. (++")$(++)<*>show$"): ท้ายสตริง")$(++)<*>show$",
  2. ('(':): การเพิ่มอักขระ'('และ
  3. (++)<*>show(= \x->x++show x): การผนวกเวอร์ชันที่ยกมาของนั้น

ส่งผลให้ใน="R""(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""

R= (Q)$(++)<*>show$"(Q)$(++)<*>show$"ทำงานโดย

  1. การสตริง"(Q)$(++)<*>show$",
  2. (++)<*>show: ผนวกรุ่นที่ยกมาของที่
  3. นำQไปใช้กับที่

ส่งผลให้ใน=Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""Q "R"

(parens รอบ ๆQมีความจำเป็นเพราะQอาจมี$ได้อย่างง่ายดายเช่นเดียวกับRและ$น่าเสียดายที่มีความเกี่ยวข้องกัน)

การสาธิต

λ> putStrLn $ ((++)<*>show).('(':).(++")$(++)<*>show$") $ "id"
(id)$(++)<*>show$"(id)$(++)<*>show$"
λ> putStrLn $ (id)$(++)<*>show$"(id)$(++)<*>show$"
(id)$(++)<*>show$"(id)$(++)<*>show$"
λ> putStrLn $ ((++)<*>show).('(':).(++")$(++)<*>show$") $ "reverse"
(reverse)$(++)<*>show$"(reverse)$(++)<*>show$"
λ> putStrLn $ (reverse)$(++)<*>show$"(reverse)$(++)<*>show$"
"$wohs>*<)++($)esrever("$wohs>*<)++($)esrever(
λ> putStrLn $ ((++)<*>show).('(':).(++")$(++)<*>show$") $ "length"
(length)$(++)<*>show$"(length)$(++)<*>show$"
λ> print $ (length)$(++)<*>show$"(length)$(++)<*>show$"
44

ไม่เพียง แต่$ต้องการวงเล็บเท่านั้น แต่ยังletรวมdoถึงการแสดงหรือแลมบ์ดา
Ørjan Johansen

@ ØrjanJohansenใช่ แต่ฉันสามารถกำหนดเซตย่อยของภาษาที่ไม่สามารถแยกแลมบ์ดา / let/ if/ case/ / doถ้าฉันไม่ปล่อยพวกมันออกมาเอง บางทีมันก็เป็นอย่างที่ฉันไม่ต้องทำ
Anders Kaseorg

2

แหล่งที่มา = เป้าหมาย = JavaScript, 66

console.log("function a(){console.log("+prompt()+"(a+'a()'))}a()")

ข้อสมมติฐานสำหรับ Q:

  • Q ควรเป็นฟังก์ชันที่ไม่ระบุชื่อ JavaScript ของสตริงต่อสตริง

ตัวอย่าง:

  • ย้อนกลับ Q =function(s) { return s.split('').reverse().join(''); }

ในกรณีนี้P(Q)(หรือR) จะได้รับ: function a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()และโดยการดำเนินการนั้นเราจะได้รับ: ซึ่งเป็นเหมือนกับ)(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnufQ(R)

  • เอกลักษณ์ Q =function(s) { return s; }

ในกรณีนี้P(Q)(หรือR) จะเป็น: function a(){console.log(function(s) { return s; }(a+'a()'))}a()ซึ่งเป็นควิน JavaScript ไม่จำเป็นต้องพูดQ(R)จะเหมือนกันเนื่องจาก Q เป็นฟังก์ชันเอกลักษณ์


หมายเหตุบางส่วน:

STDIN ในจาวาสคริปต์เป็นแบบดั้งเดิมprompt()แต่ฉันอนุญาตให้ตัวเองที่จะละเว้นจากประเพณีalert()เป็น STDOUT เพื่อที่จะทำให้กระบวนการของการเรียกใช้ผลลัพธ์เป็น progrem โดยใช้ copy-paste ได้ง่ายขึ้น (ฉันรู้ว่าฉันสามารถบันทึกอักขระได้สูงสุด 12 ตัวเมื่อเปลี่ยนเป็นalert())

ฉันสามารถทำให้สิ่งต่าง ๆ สั้นลงใน ES6 แต่ฉันต้องการพักกับ Native JavaScript สำหรับตอนนี้ ฉันกำลังพิจารณาที่จะส่ง S = Scala, T = ECMA6 คำตอบในอนาคตเพียงเพื่อประสบการณ์

ฉันรู้ว่าจาวาสคริปต์แทบจะไม่สามารถเอาชนะCJam ได้ในแต่ฉันต้องใช้ความท้าทายนี้! มันสนุกอย่างแน่นอน


ขอบคุณ! แน่นอนว่ามันจะเจ๋งมากที่มีรายการที่มีภาษาต้นทางและภาษาเป้าหมายที่แตกต่างกัน
Zgarb

2

เยลลี่7 , 9 ไบต์

“ṚƓ^ṾṂ’³3

ลองออนไลน์!

Q คือฟังก์ชัน 7 (นั่นคือไม่เกินกว่าองค์ประกอบสแต็คด้านบนและทำ I / O ผ่านสแต็ก) และได้รับเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

คำอธิบาย

โปรแกรมที่ 7

ตัวสร้าง quine สากลใน 7 ที่ฉันใช้ที่นี่คือ:

717162234430…3

สิ่งแรกที่ควรทราบก็คือผู้นำ 7 นั้นเทียบเท่ากับช่องว่างนำหน้าและไม่มีผลกระทบใด ๆ ต่อโปรแกรม เหตุผลเดียวที่มีคือการเชื่อฟังกฎของ PPCG ต่อ quines ที่เป็นตัวอักษรเท่านั้น (ซึ่งเข้ารหัสโดยโปรแกรมที่สอง1ในโปรแกรมแทนที่จะเป็นตัวมันเอง)

ส่วนที่เหลือของโปรแกรมเป็นองค์ประกอบสแต็คเดียว (มันมีความสมดุล7s และ6s) ซึ่งจะทำสิ่งต่อไปนี้เมื่อทำงาน:

717162234430…3
 1716           Push a stack element "7" onto the stack
     2          Copy it
      23        Pop and output one of the copies (selecting format 7)
        4430    Prepend it to the top of stack
             3  Output it

กล่าวอีกนัยหนึ่งองค์ประกอบสแต็กนี้เป็นโปรแกรมที่พิมพ์ด้านบนของสแต็กพร้อมกับ7prepended ในรูปแบบเอาต์พุต 7 (ซึ่งหมายถึง "พิมพ์ตัวอักษรโดยใช้การเข้ารหัสแบบเดียวกับซอร์สโค้ด" และเห็นได้ชัดว่าเป็นการเข้ารหัสที่ดีที่สุดสำหรับ quines) มันโชคดีพอสมควรที่เราสามารถนำตัวอักษรกลับมาใช้ใหม่ได้7สองวัตถุประสงค์ (รูปแบบเอาต์พุตและช่องว่างชั้นนำ) ชัดเจนโดยการแทรกบางสิ่งก่อนหน้าสุดท้าย3เราสามารถส่งออกฟังก์ชันของ7+ อินพุตแทนที่จะส่งออก7และ ป้อนข้อมูลโดยตรง

องค์ประกอบสแต็กนี้จะได้รับที่ซอร์สโค้ดของตัวเองได้อย่างไร เมื่อถึงจุดสิ้นสุดของโปรแกรม 7 evalองค์ประกอบด้านบนสแต็คโดยค่าเริ่มต้น อย่างไรก็ตามมันไม่ได้เกิดขึ้นจริงจากสแต็คในกระบวนการดังนั้นองค์ประกอบสแต็คตามตัวอักษรที่ถูกevalนำยังคงอยู่ที่นั่น (กล่าวอีกนัยหนึ่งโปรแกรมไม่ได้อ่านซอร์สของตนเอง - ดังที่เห็นได้จากความจริงที่ว่ามันไม่สามารถเห็น7จุดเริ่มต้นของโปรแกรมซึ่งเป็นตัวแยกองค์ประกอบสแต็กแทนที่จะเป็นส่วนหนึ่งของตัวอักษร - แต่ค่อนข้างมัน ประกอบด้วยตัวอักษรส่วนใหญ่ที่evalนำโดยค่าเริ่มต้น)

โปรแกรมเยลลี่

นี่อาจเป็นหนึ่งในโปรแกรมเยลลี่ที่มีลักษณะคล้ายเยลลี่น้อยที่สุดที่ฉันเคยเขียน มันประกอบด้วยสาม nilads ( “ṚƓ^ṾṂ’, ³, 3) ซึ่งมีการส่งออกเพียงแค่ในลำดับเนื่องจากไม่มีการใช้งานเกี่ยวกับพวกเขา 3เป็นที่ชัดเจนพอเพียงเป็นเลขคงที่ สิ่ง³นี้ง่ายมากถ้าคุณรู้ว่าเยลลี่: มันเป็นสัญกรณ์ชัดเจนของเจลลี่สำหรับอาร์กิวเมนต์บรรทัดคำสั่งแรก (ซึ่งเป็นที่ที่เยลลี่มักจะรับอินพุต) โปรแกรม Jelly ที่เหลือแสดงถึงตัวสร้าง Universal Quine 7 ของฉัน: โดยการใช้ประโยชน์จากข้อเท็จจริงที่ว่าคำสั่งทั้งหมดใน 7 สามารถแสดงโดยใช้หลัก ASCII เราสามารถตีความ717162234430ไม่เหมือนชุดคำสั่งหรือแม้กระทั่งเป็นเลขฐานแปด (เหมือนที่เป็นแนวคิด) แต่เป็นเลขทศนิยมหมายความว่าเราไม่ต้องการการจัดรูปแบบพิเศษสำหรับเอาต์พุต เลขทศนิยมนั้นจะกลายเป็น“ṚƓ^ṾṂ’สัญลักษณ์เลขจำนวนเต็มที่ถูกบีบอัดของเยลลี่

ตัวอย่าง

หากเราให้24053เป็นโปรแกรม Q เราจะได้ผลลัพธ์ต่อไปนี้:

717162234430240533

ลองออนไลน์!

2405 เชื่อมองค์ประกอบสแต็กด้านบนเข้าด้วยกัน:

2405   Stack   Explanation
       x
2      x|x     Duplicate top of stack
 4     x||x    Swap two stack elements, with an empty element between
  0    x|(X)   Escape the top stack element, then concatenate the top two
   5   xx      Execute the top stack element

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

ดังนั้นการรันโปรแกรมผลลัพธ์ R จึงให้ R สองชุด:

7171622344302405371716223443024053

2

CJam → CJam, 13 ไบต์

{`"_~"+7}_~qt

ลองออนไลน์!

อินพุตQควรเป็นข้อมูลโค้ดที่แก้ไขสตริงเท่านั้นในสแต็ก Qอ่านจาก stdin

ตัวอย่าง

การป้อนข้อมูล:

S*W%

มันเพิ่มช่องว่างระหว่างทุกสองตัวละครและย้อนกลับสตริง

เอาท์พุท:

{`"_~"+S*W%}_~

ผลลัพธ์ของควินทั่วไป:

~ _ } % W * S + " ~ _ " ` {

คำอธิบาย

{`"_~"+7}_~      e# Evaluate a generalized quine in CJam that only appends a 7.
q                e# Read the input.
t                e# Replace the 7th character (0-based) with the input.

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

อาจเป็น{`"_~"+ }_~7qtที่ซึ่งพื้นที่ว่างเป็นตัวยึดตำแหน่งของเพย์โหลด แต่การเปลี่ยนเพย์โหลดเพื่อ7บันทึกไบต์


1

CharcoalPerl (5), 29 33 ไบต์

A$_=q(αA);evalβαS"\α$_β\n";printβ

ลองออนไลน์!

Perl โปรแกรม Q $_ควรกลับข้อมูลโค้ดที่จะเข้าเป็นสตริงไปทางด้านขวามือและให้ผลลัพธ์ในตัวแปร (ฟังก์ชั่น Perl โดยพลการสามารถแปลงเป็นแบบฟอร์มนี้ได้โดยการตัดคำเหล่านี้เป็นsub x {…}; $_=xส่วนใหญ่แม้ว่าไวยากรณ์ของ Perl หมายความว่าไม่จำเป็นต้องมีการตัดคำ)

คำอธิบาย

Perl

นี่คือสิ่งที่ตัวสร้าง Perl Quine สากลดูเหมือนว่า:

$_=q(…"\$_=q($_);eval";print);eval

(ในกรณีส่วนใหญ่คุณต้องการลงมือทำสิ่งนี้$_=q(say…"\$_=q($_);eval");evalแต่ฉันไม่แน่ใจว่าคุณสามารถใส่รหัส Perl เข้าไปในนั้นได้เอง)

กล่าวอีกนัยหนึ่งเรามี wrapper ภายนอก$_=q(…);evalซึ่งกำหนดสตริงให้กับ$_และประเมินมัน ข้างใน wrapper คือ"\$_=q($_);eval"การประกอบใหม่ของ wrapper พร้อมกับเนื้อหาผ่านการใช้ค่าที่เราเก็บไว้$_รวมทั้งรหัส Q ที่ระบุโดยผู้ใช้รวมprintถึงการพิมพ์ผลลัพธ์ (น่าเสียดายที่เราไม่สามารถใช้ได้sayมันเพิ่มการขึ้นบรรทัดใหม่และเกี่ยวข้องกับ quines)

ถ่าน

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

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

เป็นไปได้ที่จะสั้นลงเล็กน้อย (เล็กน้อย) ตัวสร้างควินสากล Perl ประกอบด้วยสองส่วนที่ค่อนข้างยาวซ้ำ ดังนั้นเราสามารถใช้คำสั่งเพื่อกำหนดให้ตัวแปร (เช่นA…αกำหนดให้กับตัวแปรα) และเพียงแค่สอดแทรกตัวแปรในสตริงที่เราพิมพ์ผ่านการใช้ชื่อของพวกเขา ที่ช่วยประหยัดไม่กี่ไบต์ไปเพียงแค่การเขียนสตริงอย่างแท้จริง

น่าเสียดายที่ Charcoal ผนวกบรรทัดใหม่ให้กับโปรแกรมด้วย แต่นั่นไม่ใช่เรื่องใหญ่ มันมีราคาเพียงสองไบต์สำหรับการ\nเพิ่มบรรทัดใหม่นั้นให้กับอินพุตของ Q เช่นกัน

ตัวอย่าง

ถ้าเราให้อินพุต$_=reverse(ซึ่งตรงกันข้ามสตริง) เราจะได้ผลลัพธ์ต่อไปนี้:

$_=q($_=reverse"\$_=q($_);eval\n";print);eval

ลองออนไลน์!

ซึ่งเป็นควินเหมือนกันที่พิมพ์แหล่งที่มาของมันไปข้างหลังตามที่คาดไว้


1

JellyUnderloadขนาด 15 ไบต์

“(a(:^)*“S):^”j

ลองออนไลน์!

รับค่าอินพุต Underload ฟังก์ชัน Q เป็นอาร์กิวเมนต์คล้ายคำสั่ง Q ต้องรับอินพุตจากสแต็กและส่งเอาต์พุตไปยังสแต็กโดยไม่พยายามตรวจสอบองค์ประกอบสแต็กที่ลึกกว่า (เนื่องจากไม่มีอยู่)

คำอธิบาย

Underload

คอนสตรัคเตอร์ควินสากลอันเดอร์ Underload ใช้ที่นี่คือ:

(a(:^)*…S):^

โปรแกรมส่วนใหญ่เป็นตัวอักษรเดียว เราทำตามนั้นโดย:^คัดลอกจากนั้นประเมินหนึ่งสำเนา (ออกจากสำเนาอื่นในสแต็ค)

เมื่อตัวอักษรเริ่มการประเมินผลเราจะเรียกใช้a(escape ซึ่งนำกลับมาในรูปแบบเดียวกับ programA ดั้งเดิม) และ(:^)*(ซึ่งต่อท้าย:^) ดังนั้นจึงสร้างรหัสต้นฉบับของโปรแกรมขึ้นมาใหม่ แล้วเราสามารถเรียกใช้ฟังก์ชัน Q Sเพื่อแปลงนี้ในวิธีการโดยพลการและพิมพ์ผลกับ

เดอะเยลลี่

ฉันไม่สามารถใช้ Charcoal ได้ในขณะนี้เนื่องจากล่าม Underload ที่ผ่านการตรวจสอบล้มเหลวเมื่อสิ้นสุดโปรแกรมหากโปรแกรมลงท้ายด้วย newline (ล่าม Underload บางคนเช่นหนึ่งใน TIO ไม่บังคับใช้กฎนี้ แต่ฉันต้องการพกพาได้อย่างเหมาะสม) โชคไม่ดีที่ Charcoal จะเพิ่มบรรทัดใหม่ตามรอยลงในเอาต์พุต แต่ฉันใช้เจลลี่ซึ่งเกือบจะกระชับในกรณีง่าย ๆ เช่นนี้ โปรแกรมประกอบด้วยรายการตามตัวอักษรที่มีสองอิลิเมนต์ ( ““”) และรวมเข้ากับอินพุต ( j) ดังนั้นการแก้ไขอินพุตของผู้ใช้ลงในโปรแกรม

ตัวอย่าง

ใช้อินพุต:S^(พิมพ์สำเนาจากนั้นประเมินต้นฉบับ) เราได้รับโปรแกรม Underload ดังต่อไปนี้:

(a(:^)*:S^S):^

ลองออนไลน์!

สิ่งนี้พิมพ์ตัวเองหลายครั้งอย่างไม่สิ้นสุดในวิธีที่น่าสนใจพอสมควร: หลังจากทำพฤติกรรมควินปกติปกติแล้วจะทำงานevalบนสำเนาของสิ่งที่ส่งออก ที่ทำให้โปรแกรมที่ถูกสร้างใหม่ทั้งหมดทำงานอีกครั้งอย่างไม่มีกำหนด (Underload เป็นแบบเรียกซ้ำ) การฝึกฝนตัวเองและทำสิ่งevalนั้นเป็นวิธีเดียวที่จะวนลูปไม่สิ้นสุดใน Underload


Charcoal ไม่ได้เพิ่มบรรทัดใหม่ต่อท้ายอีกต่อไป (yay)
ASCII- เท่านั้น

1

RProgN 2 , 11 ไบต์

'{`{.%s}{'F

การสำรวจโปรแกรม

'{`{.%s}{'F
'{`{.%s}{'  # Push the string "{`{.%s}{" to the stack.
          F # Format the input with the top of the stack as a template. Which produces {`{.<INPUT>}{

การสำรวจควิน

ควินที่ผลิตขึ้นนั้นเรียบง่าย แต่ใช้ฟังก์ชั่นการทำงานของตัวจัดการฟังก์ชั่นที่ไม่ตรงกันใน RProgN2 เพื่อสร้างควินินสั้นและหวานเรียกว่าควิน "วนลูป" มันเป็นแนวคิดที่คล้ายกันอย่างน่าประหลาดใจกับ <> <quine

{`{.}{
{`{.}   # Push the function {`{.} to the stack.
     {  # Try to define a new function, fail, loop back to index 1. (Which in turn, skips the function definition.)
 `{     # Push the string "{" to the stack.
   .    # Concatenate the top two values of the stack, which stringifies the function, then appends { to it.
    }   # Try to terminate a function, fail quietly, and terminate the program.

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

ควินินบ้าง

  • {`{.i}{: เอาท์พุ{}i.{`{iเป็นเพียงฟังก์ชัน "ผกผัน" ดังนั้นโปรแกรมนี้จึงกลับด้านเอง
  • {`{.S§.}{: เอาท์พุ..S`{{{}§Sแปลงสตริงเป็นสแต็กของอักขระ§เรียงลำดับสแต็กพจนานุกรมจากนั้น.รวมเข้าด้วยกันกลับมาเรียงลำดับตัวเอง

ลองออนไลน์!

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