ทำให้ฉันสับสนเพื่อแก้ไขปัญหาการหยุดชะงัก


31

โปรดทราบ:โดยธรรมชาติแล้วข้อมูลจำเพาะสำหรับความท้าทายนี้ยากที่จะเข้าใจ มันอาจจะต้องมีหลักสูตรน้องใหม่อย่างน้อยในทฤษฎีการคำนวณหรือการอ่านพื้นหลังเทียบเท่า นอกจากนี้ความท้าทายนั้นค่อนข้างยาก การตอบมันจะต้องเขียนล่ามทั้งหมดสำหรับบางส่วนของภาษาที่คุณเลือกและไม่เพียงแค่นั้น แต่ล่ามจะต้องอยู่ในรูปแบบของบางอย่างเช่นควินิน หากคำตอบของคุณไม่ได้ทำทั้งหมดนี้ก็เกือบจะไม่เป็นไปตามข้อกำหนด

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

ฉันสัญญาว่าจะได้รับรางวัลเงินรางวัล 500 ชี้ไปที่คำตอบแรกที่ตรงกับสเป็คและนี้จะได้รับการตอบ BF โจของพระบาทสมเด็จพระเจ้าอยู่หัว

ความท้าทาย

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

สมมติว่าฉันได้เขียนโปรแกรมFที่มีไว้เพื่อแก้ปัญหาโปรแกรมหยุดทำงาน นั่นคือFใช้ซอร์สโค้ดของโปรแกรมอื่นเป็นอินพุตและF(G)ควรส่งคืน1ถ้าGหยุดและ0อย่างอื่น

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

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

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

  • โปรแกรมของฉันจะเขียนเป็นภาษาเดียวกับโปรแกรมของคุณและยังป้อนข้อมูลในรูปแบบของสตริงซอร์สโค้ด

  • หากโปรแกรมของฉันกลับมา0เมื่อให้โปรแกรมของคุณเป็นอินพุตโปรแกรมของคุณควรหยุด (และกลับมา0) เมื่อให้โปรแกรมของฉันเป็นอินพุต (ความหมายที่แท้จริงของ "การรักษา0" ขึ้นอยู่กับคุณ)

  • หากโปรแกรมของฉันไม่หยุดทำงานหรือหากโปรแกรมส่งคืนสิ่งอื่นนอกเหนือจาก0เมื่อให้โปรแกรมของคุณเป็นอินพุตโปรแกรมของคุณควรทำงานต่อไปเรื่อย ๆ

การบิดคือการทำให้ยากขึ้นจริงๆคุณต้องทำตามกฎต่อไปนี้:

  1. คุณไม่สามารถใช้ฟังก์ชันในตัวexecหรือevalชนิดใดก็ได้

  2. คุณไม่สามารถใช้วิธี "โกง" เพื่อรับซอร์สโค้ดของโปรแกรมของคุณเอง (เช่นคุณไม่สามารถพูดว่า "บันทึกสิ่งนี้ในไฟล์ชื่อ 'โปรแกรม'" จากนั้นมีopen(program)ในโปรแกรมของคุณ)

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

เพื่อให้ยากน้อยลงเล็กน้อยอย่างบ้าคลั่งคุณได้รับอนุญาตให้ใช้ชุดย่อย (ทัวริง) ของภาษาที่คุณเลือก ดังนั้นหากโปรแกรมของคุณเขียนด้วย Python และจะทำงานได้ก็ต่อเมื่อโปรแกรมของฉันมีเฉพาะifs และwhileลูปและการดำเนินการสตริงพื้นฐานเท่านั้นนั่นก็ถือว่าใช้ได้ตราบใดที่โปรแกรมของคุณใช้สิ่งเหล่านั้นด้วยเช่นกัน (ซึ่งหมายความว่าคุณไม่ต้องกังวลกับการใช้ไลบรารี่มาตรฐานของภาษาที่คุณเลือก!) อย่างไรก็ตามโปรแกรมของคุณจะต้องทำงานจริง - คุณไม่สามารถสร้างภาษาของคุณเองได้

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

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


หมายเหตุ: ความท้าทายนี้ถูกโพสต์เป็นการแต่มันถูกปิดในปี 2016 เนื่องจากไม่มี "เกณฑ์การชนะวัตถุประสงค์" และฉันเปลี่ยนมันเป็นเพื่อเปิดมันอีกครั้ง แต่ผมได้พบว่าเป็นของเดือนมกราคม 2018 s ไม่ได้อยู่ในความเป็นจริงห้ามใน PPCG (มีนี้เป็นส่วนใหญ่การอภิปรายที่ผ่านมาเมตา) เพื่อให้ปิดมันในครั้งแรกที่อยู่กับนโยบายของเว็บไซต์ ฉันเข้าใจว่า popcons ไม่เป็นที่นิยมในทุกวันนี้ แต่นี่เป็นความท้าทายที่เก่าแก่และธรรมชาติของมันทำให้มันไม่เหมาะสมสำหรับระบบการให้คะแนน หากใครยังรู้สึกอย่างแรงกล้าว่าไม่ควรได้รับอนุญาตให้มีการอภิปรายเมตาดาต้าก่อนที่คะแนนโหวตจะเริ่มถูกโยนทิ้ง ในที่สุดโอกาสปิดที่ใครบางคนใช้เวลาหนึ่งปีที่ผ่านมาพยายามที่จะเล่นกอล์ฟวิธีการแก้ปัญหาของพวกเขามั่นใจว่ามันจะเป็นเช่นเดียวกับการแข่งขันในความท้าทายนี้และก็เป็นที่คุ้มค่าของเงินรางวัลตามที่มันจะได้รับในรุ่น


1
เมื่อกลับมาคุณหมายถึง exit code หรือ stdout หรือไม่ หรือเป็นที่ยอมรับทั้งคู่?
PlasmaPower

ทั้งสองเป็นที่ยอมรับ
นาธาเนียล

@Nathaniel ฉันจะเอามันมันจะผิดกฎหมายที่จะส่งออกได้รับรหัสสำหรับFเข้าแฟ้มและimportไอเอ็นจีได้หรือไม่ ; 3
cjfaure

1
ฉันชอบคำถามนี้มาก แต่ยากที่จะเข้าใจ หากใครกำลังมีปัญหาภาพนิ่งทั้งสองนี้ (ใน Java psuedocode) ทำให้ฉันเข้าใจได้ง่ายขึ้นมาก: imgur.com/a/NRmyO
Harry

1
คุณพูดถึง "จิตวิญญาณของคำถาม" และ "การแก้ปัญหาของแท้" คุณหมายถึงอะไร? เราควรที่จะเขียนล่ามภาษาของเราเองหรือไม่? ฉันไม่สามารถจินตนาการวิธีการอื่นได้
KSFT

คำตอบ:


23

brainfuck , 6013 4877 4376 ไบต์

แก้ไข: -1136 ไบต์ เปลี่ยนเป็นวิธีที่ดีกว่าในการสร้างข้อมูลสำหรับควินิน

แก้ไข 2: -501 ไบต์ มาที่ล่ามตนเองของฉันอีกครั้งและตัดทอนสองสามร้อยไบต์

->++>++++>+>++>+++>>++++>>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>++++>++++>>+++>>++++>>+++>>++>++>++>++>++>++>++>++++>+++++>+>++>++>++>++>++>++>>+++>+>++>++++>+>+++>+>++++>+>+++>+>++>>>+++++>+++>>+++>+>+++++>+++++>++++>>++>+>++>++>++>++>++>++>+++>>++>++>>++++>>+++>++>++>++>++>++>++++>+++++>>++>++>++>+>+++>>++++>>++>++>++>>++>++>++>>++>++>++>>++>++>++>++>++>++>>++>++>++>++>++>++>>++>++>++>>++>++>++>++>>++>++>++>++>++++>+>+++>>+++++>+++>>++>>+++++>>>++>>++>++>++>>+++++>+++++>>>++>++>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>++++>++++>++++>>+++>>>++++>>+++>>>++++>>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++++>+++>>++++>>+++>>>++++>>+++>>>++++>>+++>>>++++>+++++>+>+>++>++++>+>+++>+>++>>>++++>>+++>>+++>+>+>++++>++++>+++++>>++>+>+++>+>+++>>>++++>>+++>>++++>++++>+++++>+>++>>+++>>+++>+>+>++++>+>+++>+>+>++++>+>+++>+>+>++++>+>+++>>+++>>>>++++>>+++>>>++++>>+++>+>++++>++++>+++++>+++>+>+++>>>>++++++>++++>>++>++>++>++>++>++>++>++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++++>+++>++>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>++>+>++>>>>>+++>+>+>+>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>>>>>+++>+>+>+>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>+++++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>++>++>++>++>++>++>>>>>+++>+>+>++>++>++>++>++++>+++++>+>+++++>+++++>+++++>+++++>+++++>+++++>>+++>++>+>++>++++>>+++>>++++>+>++>++>+>++>>>>>+++>+>+>+>+++++>+++++>++++>>+++>>++++>+>+++++>+>++>>>>>+++>+>+>+++++>+>++++>++>+++>+>++++>>+++>>++++++>+++>>>>++>+>+>+>+>+++++>++++>+>+++>>++++>+++++>++++>+>+>+++>>++++>+>++>++++>>+++>>>++++>+>+++>+>+>++++>>>++>++++>+>+>++++>+>+++>+>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>++>+>+>++++>+>+++>+>+++>+>+++++>++++>>>+++>+>++++>>>>>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>+>++>++>++++>+++++>>>++>+>+>+++>>>++++>>+++>>+++>+>+++>+>++++>+>+++>>+++++>+>+++>>+++++>++++>+>+>+++>>++++>+>++>++>++++>>+++>>>++++>+>+>+++>>++++>+>+>++>++++>+>+>++++>+>+++>>++++>+++++>+>+>++>>>+++>>+++++>+++++>++++>+>+>+++>>++++>++++>>+++>>++>+>+>++++>+>+++>+>+++>>++>++++>+>+>+++>>++++>++++>>+++>>+++++>+>+>++++>+>+++>+>+++>>++>++++>>+++>>+++>+++>+>+>++++>+>+++>>+++++>+++++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>+++++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++++++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>++++>++++>>+++>>++++>>+++>>>>++++>>+++>>>++>+>+>+>++++>+>+++>+>+>+>++++>+>+++>+>++++>+>+++>>+++++>+++>>++++>>+++>>++++>>+++>>>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>++>+>+>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>>>++++>>>+++>>++++>+>+>+>++++>+>+>+++>+>++>>>>++++>>>+++>>+++++>+++>>++++>+++++>+++>+>+>++>++++>+>++++>+++++>>>++>+>+>+++>+>+++>+>++++>+++++>>>++>+>+>+++>+>++++>+>+++>+>+++>>+++++>++++>+>+>+++>>++++>++++>>+++>>++>++>++++>+++++>+++++>>++++>+++++>+>+>++>>>+++>>+++>++>+>+>+++++>++++>++>++>+>+>+++>+>++++>+++++>>>>++++>>>+++>>++>+>+>+>++++>+>+>+++>+>+++>+>++++>+>+++>+>+++>+>++>++>++>++>++>++>++>++>>>++++>++>+>+>+++++>>>+++>>+++>>>++++>++++[<+]>[>[>]>[>]>++++++++++[-<++++++>]<++[<]<[<]<+>>-[[>]>[>]>+++++++[-<++++++>]<+[<]<[<]<+>>-]>]<--[>+<++++++]>++>[>]+++++[->+++<]>[>+++>+++>+++>++++++>++++++>+++>++++>++++[<]>-]>+>->>+>+++>-->>++[<]<<[<]<<[<]>[[[>]>>[>]>>[>]<[->>+<<]<[<]<<[<]<<[<]>-]>[>]>>[>]>>[>]>>[-<<+[<]<+>>[>]>]<<[[->+<]<]>>[>]>[[-<+>]>]<<[<]<<[<]<<[<]>]>>>[>]>>[>]<[[-]<]>>>,[>+++++++[<------>-]+<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<+<+>>>>]<<<-[>]>[<-<+++>>>>]<<<--------------[>]>[<++<+>>>>]<<<--[>]>[<-<+++++++>>>>]<<++++[-<------>]+<+[>]>[<++<+>>>>]<<<--[>]>[<-<+>>>>]<<-<[+]<[>]>,]>>>+<<<<-[<]>[-[<<]>[<+[>]>>[<]<<[>>+[<<[<]<<-[>>]<[>>>>[>]>+<<[<]<]<-[>>]<[>>>>[>]>-<<[<]<]<++[->>+<<]>>[>]>]<]<[<]>-<]>-[<<]>[<++[>]>>[<<]>[<<+[<<[<]>[-<<+>>]>--[<<]>[[>]>+<<[<]<]>+[<<]>[[>]>-<<[<]<]>+[>]>]]<<[<]>--<]>-[<<]>[[>]>>.<<<[<]<]>-[<<]>[[>]>>-<<<[<]<]>-[<<]>[[>]>>,<<<[<]<<<[<]<[<]>[[>]>[>]>>>[>]>>+<<<[<]<<<[<]<[<]>-]>[>]>[>]>>[<]<]>-[<<]>[[>]>>+<<<[<]<]>-[<<]>[[>]>>>[>>]>[<<<[<<]<+>>>[>>]>-]>[-]<<+[<[->>+<<]<]<[->>+<<]<[<]<]>-[<<]>[[>]>++[-->[-<<+>>]>]+<<-[++<<]<[->>>[>>]>+<<<[<<]<]<[<]<]<++++++++>>[+<<->>]>]>>[]

ลองออนไลน์! อินพุตที่นี่เป็นโปรแกรม cat อย่างง่าย (,[.,]) ซึ่งจะพิมพ์โปรแกรมเอง

"Return 0" ถูกกำหนดโดยสิ้นสุดโปรแกรมบนเซลล์ที่มีค่า 0

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

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

ส่วนที่ 1: การสร้างข้อมูล

->++>++++> ....... >+++++>>>+++>>+++>>>++++>+++

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

Number of Pluses
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
> | < | + | ] | [ | - | , | . |

ส่วนที่ 2: สร้างส่วนข้อมูลโดยใช้ข้อมูล

+[<+]>

[
    Add a right arrow
    >[>]>[>]>(10++++++++++)[-<(6++++++)>]<++[<]<[<]
    <+>>-
    Add the right amount of pluses
    [
        [>]>[>]>(7+++++++)[-<(6++++++)>]<+[<]<[<]<+>>-
    ]
    >
]
Add the beginning minus
<--[>+<++++++]>++

ใช้ข้อมูลจากส่วนหนึ่งเพื่อเพิ่มอักขระที่ใช้ในการสร้างข้อมูลไปยังส่วนรหัส มันเพิ่ม>ไปยังจุดสิ้นสุดของส่วนรหัสและค่าของเซลล์นั้นมีข้อดีหลายประการ

ส่วนที่ 3: สร้างรหัสที่เหลือโดยใช้ข้อมูล

Initialises the 8 characters of brainfuck
>[>]+++++[->+++<]>[>+++>+++>+++>++++++>++++++>+++>++++>++++[<]>-]
>+>->>+>+++>-->>++[<]<<[<]<<[<]>

Tape looks like:
data 0 0 code 0 0 characters

Runs through the data destructively and adds the represented symbol to the code section
[
    [
        For each plus in this cell
            Shift the gap in the characters over one
        [>]>>[>]>>[>]<[->>+<<]
        <[<]<<[<]<<[<]>-
    ]
    Navigate to character
    >[>]>>[>]>>[>]>>
    Copy the character to the end of the code section
    [-<<+[<]<+>>[>]>]

    Shift the symbol section over one
    <<[[->+<]<]
    >>[>]>[[-<+>]>]

    Navigate to next byte of data
    <<[<]<<[<]<<[<]>
]

Remove characters
>>[>]>>[>]<[[-]<]

ทำลายส่วนข้อมูลและเพิ่มรหัสที่เหลือลงในส่วนรหัส

ตอนที่ 4: รับโปรแกรมอินพุต

>>>,
[
    >(7+++++++)[<(6------)>-]+<-
    [>]>
    [plus <+<+>>>>]<<<
    -[>]>
    [comma <+<+>>>>]<<<
    -[>]>
    [minus <+<+>>>>]<<<
    -[>]>
    [dot <-<+++>>>>]<<<
    (14--------------)[>]>
    [left <++<+>>>>]<<<
    --[>]>
    [right <-<+++++++>>>>]<<
    (29++++[-<------>]+<+)
    [>]>
    [start loop <++<+>>>>]<<<
    --[>]>
    [end loop <-<+>>>>]<<
    -<[+]<[>]>,
]

รับโปรแกรมอินพุต ลบอักขระที่ไม่ใช่ brainfuck และแสดงอักขระแต่ละตัวด้วยตัวเลข:

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
] | [ | . | - | , | + | > | < |

255หมายถึงการสิ้นสุดของโปรแกรมที่มี

ตอนที่ 5: การตีความอินพุต

Initialise simulated tape
>>>+<<<<-

[<]>
[
    -[<<]>
    [end loop
        co 0 0 0 e:  _1 0 0 0 1 ?
        Check if current cell is one
        <+[>]>>[<]<<
        co 0 0 1 e _1: 0 0 !0 1
        or
        co 0 0 1 e _1 0: 0 0 1
        [ If current cell is one navigate to corresponding start loop
            Create counter
            >>+
            [
                co 0 0 de _1 0 c: !0 1
                checks if next instruction is an end loop
                <<[<]<<-
                [>>]<
                c !0 0: 0 de _1 0 c !0 1
                or
                c: 0 0  0 de _1 0 c !0 1
                [>>>>[>]>+<<[<]<] Add one to counter if it is
                checks if start loop
                <-[>>]<
                c !0 0: 0 de _1 0 c !0 1
                or
                c: 0 0  0 de _1 0 c !0 1
                [>>>>[>]>-<<[<]<] Subtract one from counter if it is
                c ? 0: 0 de _1 0 c !0 1
                Adds two to counteract checks and move to the next instruction
                <++[->>+<<]
                >>[>]>
                c 0 0 ode _1 0 c: !0 1
                End on the counter
                    If the counter is 0 then we have reached the corresponding bracket
            ]
            c 0 0 2 de _1 0 0: !0 1 0
            <
        ]
        c 0 0 1?2 de _1 0: 0 0 1 0
        Subtract one from current instruction
            This executes the start loop code next but that does nothing
        <[<]>-<
    ]
    >-[<<]>
    [start loop
        c 0 0 0 de:  _1 0 0 ? 1
        <++[>]>>[<<]>
        c 0 0 2 de _1 0 0 0 1:
        or
        c 0 0 2 de _1 0 0: !0 1
        [ If current cell is 0 navigate to corresponding end loop
            Initialise counter
            <<+
            c 0 0 ode _1 0 c: 0 1
            [ While counter is not 0
                Transfer current instruction over (first instruction is guaranteed to be start loop)
                <<[<]>[-<<+>>]>
                co 0 0 de _1 0 c: 0 1
                Check if start loop
                --[<<]>
                co 0 0: !0 e _1 0 c 0 1
                or
                co 0 0 0 e _1 0 c 0 1
                [[>]>+<<[<]<] Add one to counter if so
                checks if end loop
                >+[<<]>
                co 0 0: !0 e _1 0 c 0 1
                or
                co 0 0 0 e:  _1 0 c 0 1
                [[>]>-<<[<]<] Subtract one from counter if so
                Add one to counteract checks and navigate to counter
                >+[>]>
                co 0 0 de _1 0 c: 0 1
                End on counter
                    If counter is 0 then we have reached the corresponding end loop
            ]
            co 0 1 e _1 0 0: 0 1
        ]
        co 0 0 2?1 e _1 0 0: ? 1
        Subtract two from the current instruction to bring it back up to the right value
        <<[<]>--<
    ]
    3 of these are pretty self explanatory
    Navigate to the current cell and execute the instruction on it
    >-[<<]>
    [output
        [>]>>.<<<[<]<
    ]
    >-[<<]>
    [minus
        [>]>>-<<<[<]<
    ]
    >-[<<]>
    [input
        Reset current cell
        [>]>>, (no more input so this is set to 0)
        co 0 0 0 e:  _1 0 0 0: 1 b 1 a 0 d 1 e 1 f
        Navigate to start of code section
        <<<[<]<<<[<]<[<]>
        d: ata 0 co 0 0 0 e _1 0 0 0 1 b
        or
        0: co 0 0 0 e _1
        Transfer next instruction to current cell
        [[>]>[>]>>>[>]>>+<<<[<]<<<[<]<[<]>-]
        0: ata 0 co 0 0 0 e _1 0 0 d 1 b
        or
        0: co 0 0 0 e _1
        Navigate back to the normal spot
        >[>]>[>]>>[<]<
    ]
    >-[<<]>
    [plus
        [>]>>+<<<[<]<
    ]
    >-[<<]>
    [right
        Simulated tape looks like:
            a b c: d e f
        co 0 0 0 e:  _1 0 0 c 1 b 1 a 0 d 1 e 1 f
        Navigate to value of cell to the right
        [>]>>>[>>]>
        co 0 0 0 e _1 0 0 c 1 b 1 a 0 d: 1 e 1 f
        Transfer it to temporary cell
        [<<<[<<]<+>>>[>>]>-]
        co 0 0 0 e _1 d 0 c 1 b 1 a 0 0: 1 e 1 f
        Pop extra marker if it exists from the right cells and add one to the left
        >[-]<<+
        co 0 0 0 e _1 d 0 c 1 b 1 a 1: 0 0 e 1 f
        Transfer all left cells over 2 cells
        [<[->>+<<]<]<[->>+<<]
        co 0 0 0 e _1 0: 0 d 1 c 1 b 1: a 0 e 1 f
        Navigate back to normal spot
        <[<]<
    ]
    >-[<<]>
    [left
        Simulated tape looks like:
            a b c: d e f
        co 0 0 0: e _1 0 0 c 1 b 1 a 0 d 1 e 1 f
        Add temporary marker
        [>]>++
        co 0 0 0 e _1 0 2: c 1 b 1 a 0 d 1 e 1 f
        Remove temporary marker and transfer all left cells over two
        [-->[-<<+>>]>]
        co 0 0 0 e _1 c 0 b _1 a _1 0 0: d 1 e 1 f
        Add marker to right cells remove marker from left cells and reset left cell's markers
        +<<-[++<<]<
        co 0 0 0 e _1 c: 0 b 1 a 0 0 1 d 1 e 1 f
        Transfer current cell to to right cells
        [->>>[>>]>+<<<[<<]<]
        co 0 0 0 e _1 0: 0 b 1 a 0 c 1 d 1 e 1 f
        Navigate back to normal spot
        <[<]<
    ]
    Add 8 to reverse checks
    <(8++++++++)>>

    Execute next instruction
    [+<<->>]>
]

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

ตอนที่ 6: หยุดถ้าผลตอบแทนไม่ใช่ 0

>>[]

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

ทดสอบอินพุต:

ส่งคืนค่า 0 เสมอ (หยุดและส่งคืน 0)

(empty program)

ส่งคืน 1 เสมอ (รันตลอดไป)

+

ส่งคืนอินพุตทั้งหมดที่รวมเข้าด้วยกัน mod 256 (ส่งคืน 211 ดังนั้นจึงรันตลอดไป)

,[[->+<],]>

ส่งกลับค่า 0 หากอักขระสองตัวสุดท้ายของรหัสเป็นวงวนไม่สิ้นสุด ( []) ( โปรแกรมของคุณคืน 0 เมื่อให้โปรแกรมของฉันดังนั้นโปรแกรมของฉันจึงหยุด)

,[>,]>(9+++++++++)[-<(10++++++++++)>]<[-<-<->>]+<---[[-]>[-]<]<-[[-]>>[-]<<]>+>[-<->]<    

Fun Fact สำหรับผู้ที่ยังอ่านหนังสืออยู่

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

If cell1 == 0:
    Get input into cell1
If cell1 == 1 or cell1 == 0:
    Return 1
Else:
    Initialise self-interpreter-quine function
    Pass cell1-1 into cell1 of the function
    Run function
    Multiply cell1 by the return value
    Return cell1

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


เย้! BTW ถ้าคุณต้องการเล่นกอล์ฟนี้เนื่องจากการกลับมาของคุณฉันคิดว่าคุณสามารถสนับสนุน.ได้ แม้ว่านี่จะไม่ใช่คำถามจากการเขียนโค้ดอีกต่อไปการสนับสนุนภาษาทั้งหมดอาจจะน่าประทับใจกว่า
Ørjan Johansen

@ ØrjanJohansenฉันอาจเล่นกอล์ฟเป็นพัน ๆ ไบต์ได้โดยสลับไปใช้วิธีการสร้างข้อมูลที่แตกต่างกันเพียงอย่างเดียว นอกจากนี้ล่ามแปลภาษาไม่ใช่ตัวที่เล็กที่สุดที่ฉันสามารถเขียนได้เพราะมันรองรับเซลล์เชิงลบ
Jo King

ดูเหมือนว่ามันจะชนะรางวัล แต่ฉันต้องการใช้เวลาในการทำความเข้าใจไม่ใช่เป็นผู้เชี่ยวชาญ BF คุณช่วยส่ง Ping ให้ฉันได้ไหมถ้าคุณไม่ได้รับการตอบกลับในสัปดาห์หน้า
นาธาเนียล

1
ฉันยืนยันว่าสิ่งนี้ตรงตามข้อกำหนดเท่าที่ฉันสามารถบอกได้ เงินรางวัลควรจะพุ่งเข้าหาคุณในไม่ช้า (มีความล่าช้าก่อนที่ระบบจะให้รางวัลแก่ฉัน) ขอขอบคุณสำหรับคำตอบขอบคุณมาก
นาธาเนียล

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