เอาต์พุตทุกโปรแกรมที่หยุดทำงาน (เขียนล่ามแบบขนาน)


26

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

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

 step#  p1 p2 p3 p4 p5 p6
     1  X  X  X  X  X  X
     2  X  X  X  X  X  
     3  X  X     X  X
     4  X  X     X  X
     5  X  X     X
     6     X     X
     7     X     X
     8     X     X
     9     X     X
     ∞     X     X

อย่างที่คุณบอกโปรแกรม 2 และ 4 ไม่หยุด หากคุณต้องดำเนินการครั้งละหนึ่งครั้งคอนโทรลเลอร์ของคุณจะติดอยู่ในลูปไม่สิ้นสุดนั่นคือโปรแกรม 2 และไม่เคยออกโปรแกรม 3 และอื่น ๆ

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

 step#  p1 p2 p3 p4 p5 p6
     1  A  C  F  J  N  R  V
     2  B  E  I  M  Q  *  Z
     3  D  H  *  P  U
     4  G  L     T  Y
     5  K  O     X
     6  *  S     .
     7     W     .
     8     .     .
     9     .     .
     ∞     .     .

ข้อกำหนดสำหรับภาษาเป้าหมาย

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

ตัวอย่างเช่นหากคุณเลือกทดสอบ brainfuck วิธีที่ดีที่สุดคือทดสอบ[]-+<>เซ็ตย่อยเนื่องจากอินพุตไม่ได้รับการสนับสนุนและเอาต์พุตถูกทิ้ง (ดูด้านล่าง)

เมื่อพูดถึงโปรแกรม "คอนโทรลเลอร์" (ที่คุณเล่นกอล์ฟ) ไม่มีข้อกำหนดพิเศษ มีข้อ จำกัด ด้านภาษาปกติ

วิธีสร้างรายการโปรแกรมที่ไม่มีที่สิ้นสุด

ภาษาโปรแกรมส่วนใหญ่สามารถแสดงเป็นชุดของสัญลักษณ์จากตัวอักษรที่ จำกัด ในกรณีนี้มันค่อนข้างง่ายที่จะระบุรายการของทุกโปรแกรมที่เป็นไปได้เพื่อเพิ่มความยาว ตัวอักษรที่คุณใช้ควรเป็นตัวแทนของความต้องการของภาษาเป้าหมาย ในกรณีส่วนใหญ่ ASCII นี้สามารถพิมพ์ได้ หากภาษาของคุณรองรับ Unicode เป็นคุณสมบัติเพิ่มเติมคุณไม่ควรทดสอบชุดอักขระ Unicode ที่เป็นไปได้รวมกันแค่ ASCII หากภาษาของคุณใช้อย่างเดียว[]-+<>อย่าทดสอบชุดอักขระ ASCII แบบ "ความคิดเห็น" ที่หลากหลาย ภาษาเช่น APL จะมีตัวอักษรพิเศษของตัวเอง

หากอธิบายภาษาของคุณได้ดีที่สุดในวิธีที่ไม่ใช่ตัวอักษรบางตัวเช่น Fractran หรือ Turing Machines แสดงว่ามีวิธีการอื่นที่ถูกต้องพอ ๆ กันในการสร้างรายการโปรแกรมที่ใช้ได้ทั้งหมด

การตีความรายการโปรแกรมที่กำลังเติบโต

ส่วนสำคัญของความท้าทายนี้คือการเขียนล่ามแบบขนานสำหรับรายการที่เพิ่มขึ้นของโปรแกรม มีขั้นตอนพื้นฐานบางประการสำหรับสิ่งนี้:

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

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

กฎเพิ่มเติม

  • คุณต้องไม่วางไข่เธรดใหม่เพื่อให้มีโปรแกรมที่ถูกทดสอบเนื่องจากนี่จะเป็นการลดภาระการทำงานแบบขนานไปยังโฮสต์ OS / ซอฟต์แวร์อื่น ๆ
  • แก้ไข: เพื่อปิดช่องโหว่ในอนาคตคุณไม่ได้รับอนุญาตให้eval(หรือฟังก์ชั่นที่เกี่ยวข้อง) เป็นส่วนหนึ่งของรหัสโปรแกรมที่ทดสอบ คุณสามารถ eval codeblock จากรหัสของล่าม (คำตอบ BF-in-Python ยังคงใช้ได้ภายใต้กฎเหล่านี้)
  • นี่คือ
  • ภาษาที่คุณเขียนไม่จำเป็นต้องเป็นภาษาเดียวกับภาษาที่คุณกำลังทดสอบ / ส่งออก
  • คุณควรถือว่าหน่วยความจำที่มีอยู่นั้นไม่ได้ จำกัด
  • เมื่อพิสูจน์ความสมบูรณ์ของทัวริงคุณอาจสมมติว่าอินพุตถูกเข้ารหัสในโปรแกรมและเอาต์พุตสามารถอ่านได้จากสถานะภายในของโปรแกรม
  • หากโปรแกรมของคุณแสดงผลออกมาเองมันอาจผิดหรือเป็นรูปหลายเหลี่ยม

7
ฉันใช้เวลานานเกินไปที่จะตระหนักว่าทำไม"If your program outputs itself, it is probably wrong or a polyglot."
trichoplax

1
เราขอสมมติว่าหน่วยความจำที่มีอยู่นั้นไม่ จำกัด (ฉันไม่คิดว่ามันจะเป็นไปได้)
KSab

1
@KSab ใช่แล้วมันเป็นไปไม่ได้แน่นอน
PhiNotPi

1
ความท้าทายในการติดตามผล ( ยากกว่ามาก ): ให้ผลลัพธ์ทุกโปรแกรมที่ไม่หยุด
Milo Brandt

1
สามารถส่งออกโปรแกรมเดียวกันมากกว่าหนึ่งครั้งได้หรือไม่?

คำตอบ:


9

subleq OISC ใน Python, 317 269 ​​ไบต์

import collections
g=0
P={}
while 1:
    P[g]=[[0],collections.defaultdict(int,enumerate(list(int(x)for x in reversed(str(g)))))]
    g+=1
    for o,[a,p]in P.items():
        i=a[0]
        p[i+p[i+1]]-=p[i+p[i]]
        if p[i+p[i+1]]<=0:a[0]+=p[i+2]
        else:a[0]+=3
        if a[0]<0:print o;del P[o]

https://esolangs.org/wiki/Subleq

โปรแกรม subleq เป็นรายการจำนวนเต็ม (p) ที่ขยายได้และตัวชี้คำสั่ง (i) ชุดย่อยย่อยนี้ใช้การกำหนดที่อยู่แบบสัมพันธ์ซึ่งหน้าพูดคุยของ Wiki จะต้องใช้เพื่อการทำให้สมบูรณ์โดยมีค่าขอบเขต แต่ละเห็บการดำเนินการที่p[i+p[i+1]]-=p[i+p[i]]จะดำเนินการแล้วi+=p[i+2]ถ้าผลการดำเนินงานเป็น <= 0 i+=3มิฉะนั้น หากฉันเป็นลบโปรแกรมจะหยุด

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

Output:
21 (which represents the program [1 2 0 0 0 0 0...]
121
161
221
271
351
352
461
462
571
572
681
682
791
792

เอาท์พุทจะกลับรายการสำหรับเหตุผลในการเล่นกอล์ฟ ข้อมูลจำเพาะข้างต้นอาจได้รับการแก้ไขในทางกลับกัน แต่จากนั้นจะไม่ตรงกับรหัสที่ใช้ในการนำไปใช้ดังนั้นฉันจึงไม่ได้อธิบายอย่างนั้น

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


9

แท็กวงจร Bitwiseใน CJam, 98 87 84 77 ไบต์

L{Z):Z2b1>_,,1>\f{/([\:~]a2*}+{)~[\({1+(:X+\_0=Xa*+}{0+\1>}?_{]a+}{];p}?}%1}g

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

BCT เป็นตัวแปรที่เรียบง่ายของวงจรระบบแท็ก โปรแกรมถูกกำหนดโดยสตริงไบนารีสองรายการ: รายการคำสั่ง (วงจร) และสถานะเริ่มต้น เพื่อให้ชีวิตของฉันง่ายขึ้นเมื่อพิมพ์โปรแกรมฉันได้กำหนดสัญลักษณ์ของตัวเอง: สตริงแต่ละตัวจะได้รับเป็นอาร์เรย์จำนวนเต็มสไตล์ CJam และโปรแกรมทั้งหมดล้อมรอบ[[...]]ด้วยเช่น

[[[0 0 1 1] [0 1 1 1 0]]]

ฉันไม่อนุญาตสถานะเริ่มต้นว่างเปล่าหรือรายการคำสั่งว่าง

คำแนะนำใน BCT ตีความได้ดังนี้:

  • หากคำแนะนำคือ0ลบบิตนำจากสถานะปัจจุบัน
  • ถ้าการเรียนการสอนเป็นอ่านบิตอื่นออกรายการการเรียนการสอนที่โทร1 Xถ้าบิตนำหน้าจากสถานะปัจจุบัน1ผนวกXกับสถานะปัจจุบันไม่เช่นนั้นจะไม่ทำอะไรเลย

หากสถานะปัจจุบันว่างเปล่าโปรแกรมจะหยุดทำงาน

โปรแกรมหยุดชั่วคราวสองสามโปรแกรมแรกคือ

[[[0] [0]]]
[[[0] [1]]]
[[[0 0] [0]]]
[[[0] [0 0]]]
[[[0 0] [1]]]
[[[0] [0 1]]]
[[[0 1] [0]]]
[[[0] [1 0]]]
[[[0 1] [1]]]
[[[0] [1 1]]]

หากคุณต้องการดูเพิ่มเติมให้ตรวจสอบรุ่นในล่ามออนไลน์ที่ฉันลิงค์ด้านบน

คำอธิบาย

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

ส่วนที่เหลือของรหัสคือวงวนไม่สิ้นสุด{...1}gซึ่งเพิ่มโปรแกรมหนึ่งรายการขึ้นไปในรายการนี้ก่อนและคำนวณหนึ่งขั้นตอนในแต่ละโปรแกรม โปรแกรมที่หยุดพิมพ์และลบออกจากรายการ

ฉันแจกแจงโปรแกรมด้วยการนับเลขฐานสอง ตัวเลขหลักนำถูกตัดออกเพื่อให้แน่ใจว่าเราสามารถรับโปรแกรมทั้งหมดด้วย 0s ชั้นนำเช่นกัน สำหรับการแทนค่าไบนารี่ที่ถูกตัดทอนแต่ละอันฉันผลักหนึ่งรายการสำหรับแต่ละการแยกที่เป็นไปได้ระหว่างคำแนะนำและสถานะเริ่มต้น เช่นถ้าเคาน์เตอร์อยู่ในขณะนี้ที่เป็นตัวแทนไบนารีของมันคือ42 101010เรากำจัดผู้นำ1และผลักดันตัวต่อที่ไม่ว่างเปล่าทั้งหมด:

[[[0] [1 0 1 0]]]
[[[0 1] [0 1 0]]]
[[[0 1 0] [1 0]]]
[[[0 1 0 1] [0]]]

เนื่องจากเราไม่ได้ต้องการคำแนะนำที่ว่างเปล่าหรือรัฐที่เราจะเริ่มนับวันที่ 4 [[[0] [0]]]ซึ่งจะช่วยให้ การแจงนับนี้จะทำโดยรหัสต่อไปนี้:

Z):Z    e# Push Z (initially 3), increment, and store in Z.
2b1>    e# Convert to base 2, remove initial digit.
_,      e# Duplicate and get the number of bits N.
,1>     e# Turn into a range [1 .. N-1].
\       e# Swap the range and the bit list.
f{      e# Map this block onto the range, copying in the bit list on each iteration.
  /     e#   Split the bit list by the current value of the range.
  (     e#   Slice off the first segment from the split.
  [     
    \:~ e#   Swap with the other segments and flatten those.
  ]     e#   Collect both parts in an array.
  a2*   e#   Make an array that contains the program twice, as the initial state is the
        e#   same as the program itself.
}
+       e# Add all of these new programs to our list on the stack.

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

)~     e# Remove the second half of the pair and unwrap it.
[      e# We need this to wrap the instructions and current state back in an array
       e# again later.
\(     e# Bring the instruction list to the top and remove the leading bit.
{      e# If it's a 1...
  1+   e#   Append a 1 again (the instructions are cyclic).
  (:X+ e#   Remove the next bit, store it in X and also append it again.
  \_0= e#   Bring the current state to the top, get its first bit.
  Xa*+ e#   Append X if that bit was 1 or nothing otherwise.
}{     e# Else (if it's a 0...)
  0+   e#   Append a 0 again (the instructions are cyclic).
  \1>  e#   Discard the leading bit from the current state.
}?
_      e# Duplicate the current state.
{      e# If it's non-empty...
  ]a+  e#   Wrap instructions and state in an array and add them to the program
       e#   pair again.
}{     e# Else (if it's empty)...
  ];p  e# Discard the instructions and the current state and print the program.
}?

ดีมาก (+1) บางไบต์อาจถูกบันทึกโดยใช้ความจริงที่ว่า BCT กำลังทัวริงเสร็จสมบูรณ์แม้ว่าจะถูก จำกัด ให้ใช้เพียง 1 เป็น datastring เริ่มต้น ("สถานะ" ของคุณ) เช่นตีความแต่ละจำนวนเต็มบวกต่อเนื่องในไบนารีเป็น 1P จากนั้นดำเนินการ P ใน 1 และการดำเนินการ P เอาท์พุท P iff ยุติ (dovetailing อีกครั้ง) (แน่นอนว่า P ใด ๆ ที่ขึ้นต้นด้วย 0 จะอยู่ในรายการเนื่องจากจะลบการเริ่มต้น datastring ทันที)
res

8

Brainfuck ใน Python ขนาด 567 ไบต์

วิธีแก้ปัญหาที่ค่อนข้างง่ายเนื่องจาก Brainfuck เป็นภาษาที่ยากที่สุดในการเขียนล่าม

การนำไปใช้ของ Brainfuck มีตัวชี้ข้อมูลเริ่มต้นที่ 0 อนุญาตให้รับค่าบวกเท่านั้น (ถือว่าเป็นข้อผิดพลาดหากพยายามไปทางซ้ายของ 0) เซลล์ข้อมูลสามารถใช้ค่าตั้งแต่ 0 ถึง 255 และตัดคำ 5 คำแนะนำที่ถูกต้องคือ><+[]( -ไม่จำเป็นเนื่องจากการห่อ)

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

o="><+]["
A="[]if b%s1<0else[(p,a+1,b%s1,t+[0],h)]"
C="[(p,h[a]+1,b,t,h)if t[b]%s0else(p,a+1,b,t,h)]"
I=lambda s,i:i*">"if""==s else o[o.find(s[0])+i-5]+I(s[1:],i*o.find(s[0])>3)
s="";l=[]
while 1:
 s=I(s,1)
 r=[];h={}
 for i in range(len(s)):
    if s[i]=="[":r+=[i]
    if s[i]=="]":
     if r==[]:break
     h[r[-1]]=i;h[i]=r[-1];r=r[:-1]
 else:
    if r==[]:
     l+=[(s,0,0,[0],h)];i=0
     while i<len(l):
        p,a,b,t,h=l[i]
        if a>=len(p):print p;l[i:i+1]=[]
        else:l[i:i+1]=eval([A%("+","+"),A%("-","-"),"[(p,a+1,b,t[:b]+[(t[b]+1)%256]+t[b+1:],h)]",C%">",C%"=="][o.find(p[a])]);i+=1

ouputs สองสามตัวแรก:

>
+
>>
+>
><
>+
++
[]
>>>
+>>

และรายการแรก 2000: http://pastebin.com/KQG8PVJn

และรายการสุดท้ายของผลลัพธ์ 2,000 รายการแรกที่มี[]อยู่ในนั้น: http://pastebin.com/iHWwJprs
(ส่วนที่เหลือทั้งหมดมีความสำคัญตราบเท่าที่ยังใช้ได้)

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


1
ทั้งไฟล์เปล่า[-]และ[+]ควรปรากฏอย่างแน่นอนเพราะเนื้อหาของลูปนั้นถูกข้ามไปอย่างง่ายดาย
PhiNotPi

@ Sp3000 [-]และ[+]เป็นข้อผิดพลาดที่ควรได้รับการแก้ไขในขณะนี้และฉันได้อัปเดตการตั้งค่าแล้ว
KSab

1
ทำไมคุณจะสนับสนุน.? ไม่จำเป็นสำหรับชุดย่อยของทัวริงที่สมบูรณ์และควรละเว้นสิ่งต่อไป นอกจากนี้เนื่องจากคุณกำลังตัดค่าเซลล์ที่อยู่รอบ ๆ ผมคิดว่าคุณต้องการเพียงหนึ่งของและ- +
Martin Ender

@ MartinBüttnerฉันดูเหมือนจะเข้าใจผิดคำถาม ฉันไม่ได้อ่านส่วน 'เซตย่อยที่สมบูรณ์' อย่างไรก็ตามสิ่งนี้ไม่ได้ทำให้ความท้าทายเกือบเทียบเท่ากับภาษา (ส่วนใหญ่)? couldnt คุณเพียงแค่ทำให้การเปลี่ยนที่ 1-1 กับ brainfuck (หรือบางทีบางสิ่งบางอย่างได้ง่าย) เช่นรหัสคที่นี่: en.wikipedia.org/wiki/Brainfuck#Commands
KSab

2
ดูstackoverflow.com/questions/1053931/…โดยเฉพาะรายการ OISC ดูที่ CA Rule 110 และ Cyclic Tag Systems ด้วย มีห้องมากมายสำหรับการเลือก "ภาษา" ที่สมบูรณ์แบบในการท้าทายนี้
Sparr

5

เครื่องหมายทับใน Python ขนาด 640 498

g=2
P={}
while 1:
    b=bin(g)[3:]
    P[b]=[[0],['',''],[b]]
    g+=1
    for d,[a,b,c]in P.items():
        s=c[0]
        if a[0]:
            if s.count(b[0]):s=s.replace(b[0],b[1],1)
            else:a[0]=0
        else:
            if s[0]=='0':
                if len(s)==1:del P[d];continue
                s=s[2:]
            else:
                b[0]=b[1]=''
                a[0]=1
                t=p=0
                while t<2:
                    p+=1
                    if p>=len(s):break
                    if s[p]=='0':
                        if p+1>=len(s):break
                        b[t]+=s[p+1]
                        p+=1
                    else:t+=1
                if t<2:del P[d];continue
        c[0]=s
        if len(s)==0:print d;del P[d]

https://esolangs.org/wiki////

โปรแกรมสแลชเป็นสตริงในล่ามนี้ จำกัด เฉพาะอักขระ '/' และ '\' ในการดำเนินการนี้ / คือ '1' และ \ คือ '0' เพื่ออนุญาตให้เล่นกอล์ฟบางส่วนด้วยการใช้ python bin (x) เมื่อล่ามพบ \ ตัวละครตัวถัดไปคือผลลัพธ์และตัวละครทั้งสองจะถูกลบออก เมื่อพบ / มันจะค้นหาและแทนที่รูปแบบเป็น / search / replace / รวมถึงอักขระที่ใช้ Escape ภายในรูปแบบ (\\ หมายถึง \ และ \ / \ / หมายถึง) การดำเนินการแทนที่นั้นจะถูกดำเนินการบนสตริงซ้ำ ๆ จนกระทั่งสตริงการค้นหาไม่มีอยู่อีกต่อไปจากนั้นการตีความจะดำเนินต่อไปตั้งแต่ต้น โปรแกรมหยุดทำงานเมื่อไม่มีข้อมูล โปรแกรมจะถูกฆ่าหากมีชุด / รูปแบบ unclosed หรือ a \ ที่ไม่มีตัวอักษรหลังจากนั้น

Example output and explanations:
01 outputs '1' and halts
00 outputs '0' and halts
0101 outputs '11' and halts
0100 ...
0001
0000
010101
010100
010001
010000 ...
101110 replaces '1' with '', leaving '00', which outputs '0' and halts

4

Treehuggerใน Java, 1,299 1,257 1,251 1,207 1,203 1,201 1,193 1,189 ไบต์

import java.util.*;class I{static class N{N l,r;byte v;}static class T extends Stack<N>{{push(new N());}void p(){pop();if(size()==0)p();}int i,h;char[]s;}static void s(T t){if(t.i>=t.s.length){t.h=1;return ;}char c=t.s[t.i];if(c=='<'){if(t.peek().l==null)t.peek().l=new N();t.push(t.peek().l);}if(c=='>'){if(t.peek().r==null)t.peek().r=new N();t.push(t.peek().r);}if(c=='^')t.p();if(c=='+')t.peek().v++;if(c=='-')t.peek().v--;if(c=='['&&t.peek().v==0){int i=1;while(i>0){t.i++;if(t.s[t.i]==']')i--;if(t.s[t.i]=='[')i++;}return;}if(c==']'&&t.peek().v!=0){int i=1;while(i>0){t.i--;if(t.s[t.i]==']')i++;if(t.s[t.i]=='[')i--;}return;}t.i++;}static char[]n(char[]a){String b="<^>[+-]";int q=a.length;for(int i=q-1;i>=0;i--){int j=b.indexOf(a[i]);if(j<6){a[i]=b.charAt(j+1);return a;}a[i]='<';}a=Arrays.copyOf(a,q+1);a[q]='<';return a;}public static void main(String[]a){List<T>z=new ArrayList<T>();char[]c={};while(true){T t=new T();t.s=c;if(b(c))z.add(t);c=n(c.clone());for(T u:z)try{s(u);if(u.h>0){z.remove(u);System.out.println(u.s);break;}}catch(Exception e){z.remove(u);break ;}}}static boolean b(char[]c){int i=0;for(char d:c){if(d=='[')i++;if(d==']')i--;if(i<0)return 0>0;}return i==0;}}

4

Brachylogปัญหาการโพสต์จดหมาย , 10 ไบต์

≜;?{~c}ᵐ\d

ลองออนไลน์!

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

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

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

คำอธิบาย

≜;?{~c}ᵐ\d
≜           Brute-force all numbers:
 ;?           Pair {the number} with {itself}
   {  }ᵐ      For each pair element:
    ~c          Brute-force a partition of that element into substrings
        \     such that the two elements each have the same number of substrings
        \     and group together corresponding substrings
         d    and remove duplicated pairs {to produce a possible output}

2

"สีม่วงไม่มี I / O" ใน Ceylon, 662

import ceylon.language{l=variable,I=Integer,m=map,S=String}class M(S d){l value t=m{*d*.hash.indexed};l I a=0;l I b=0;l I i=0;I g(I j)=>t[j]else 0;value f=m{97->{a},98->{b},65->{g(a)},66->{g(b)},105->{i},49->{1}};value s=m{97->((I v)=>a=v),98->((I v)=>b=v),65->((I v)=>t=m{a->v,*t}),66->((I v)=>t=m{b->v,*t}),105->((I v)=>i=v)};I&I(I)x{throw Exception(d);}I h(I v)=>f[v]?.first else x;shared void p(){(s[g(i)]else x)(h(g(i+1))-h(g(i+2)));i+=3;}}shared void run(){value a='!'..'~';{S*}s=expand(loop<{S*}>{""}((g)=>{for(c in a)for(p in g)p+"``c``"}));l{M*}r={};for(p in s){r=[M(p),*r];for(e in r){try{e.p();}catch(x){print(x.message);r=r.filter(not(e.equals));}}}}

สีม่วงเป็นภาษาคำสั่งเดียวที่แก้ไขได้ด้วยตนเองซึ่งถูกขอให้ตีความที่นี่ขอให้ตีความที่นี่ในฐานะที่เป็น input และ output ไม่เกี่ยวข้องสำหรับงานนี้ผมเอาoความหมายของสัญลักษณ์จากล่ามเช่นที่ (อาจ) สัญลักษณ์ที่ถูกต้องเป็นเพียงa, b, A, B, iและ1(คนสุดท้ายเพียงสำหรับการอ่านไม่ได้สำหรับการเขียน)

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

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

ล่าม "คู่ขนาน" ของฉันจึงสร้างสตริง จำกัด ทั้งหมดจากตัวละครเหล่านั้น (ในการเพิ่มความยาวและลำดับคำศัพท์) และลองแต่ละตัว

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

ฉันคิดว่าโปรแกรมที่ไม่หยุดชะงักเป็นครั้งแรกตามลำดับที่ล่ามของฉันลองใช้คือaaaiaaซึ่งในขั้นตอนแรกจะกำหนดaลงทะเบียนเป็น 0 (ซึ่งเป็นแล้ว) และขั้นที่สองและทุกขั้นตอนต่อไปนี้จะตั้งค่าตัวชี้คำสั่งกลับเป็น 0 ทำให้มันทำงานiaaอีกครั้ง

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

นี่เป็นเวอร์ชันที่มีความคิดเห็นและจัดรูปแบบ:

// Find (enumerate) all halting programs in (a non-I/O subset of) Purple.
//
// Question:  https://codegolf.stackexchange.com/q/51273/2338
// My answer: https://codegolf.stackexchange.com/a/65820/2338

// We use a turing-complete subset of the Purple language,
// with input and output (i.e. the `o` command) removed.

import ceylon.language {
    l=variable,
    I=Integer,
    m=map,
    S=String
}

// an interpreting machine.
class M(S d) {
    // The memory tape, as a Map<Integer, Integer>.
    // We can't modify the map itself, but we
    // can replace it by a new map when update is needed.
    l value t = m {
        // It is initialized with the code converted to Integers.
        // We use `.hash` instead of `.integer` because it is shorter.
        *d*.hash.indexed
    };

    // three registers
    l I a = 0;
    l I b = 0;
    l I i = 0;

    // get value from memory
    I g(I j) =>
            t[j] else 0;

    // Map of "functions" for fetching values.
    // We wrap the values in iterable constructors for lazy evaluation
    //  – this is shorter than using (() => ...).
    // The keys are the (Unicode/ASCII) code points of the mapped
    // source code characters.
    value f = m {
        // a
        97 -> { a },
        // b
        98 -> { b },
        // A
        65 -> { g(a) },
        // B
        66 -> { g(b) },
        // i
        105 -> { i },
        // 1
        49 -> { 1 }
    };

    // Map of functions for "storing" results.
    // The values are void functions taking an Integer,
    // the keys are the ASCII/Unicode code points of the corresponding
    // source code characters.
    value s = m {
        // a
        97 -> ((I v) => a = v),
        // b
        98 -> ((I v) => b = v),
        // Modification of the memory works by replacing the map with
        // a new one.
        // This is certainly not runtime-efficient, but shorter than
        // importing ceylon.collections.HashMap.
        // A
        65 -> ((I v) => t = m { a->v, *t }),
        // B
        66 -> ((I v) => t = m { b->v, *t }),
        // i
        105 -> ((I v) => i = v)
    };


    // Exit the interpretation, throwing an exception with the machine's
    // source code as the message.  The return type is effectively `Nothing`,
    // but shorter (and fits the usages).
    I&I(I) x {
        throw Exception(d);
    }

    // accessor function for the f map
    I h(I v) =>
            f[v]?.first else x;

    // a single step
    shared void p() {
        (s[g(i)] else x)(h(g(i + 1)) - h(g(i + 2)));
        i += 3;
    }
}

// the main entry point
shared void run() {
    // the alphabet of "Purple without I/O".
    value a = '!'..'~';
    //// possible alternative to use a command line argument:
    // value a = process.arguments[0] else '!'..'~';

    // an iterable consisting of all programs in length + lexicographic order
    {S*} s =
            // `expand` creates a single iterable (of strings, in this case)
            // from an iterable of iterables (of strings).
             expand(
        // `loop` creates an iterable by applying the given function
        // on the previous item, repeatedly.
        // So here we start with the iterable of length-zero strings,
        // and in each iteration create an iterable of length `n+1` strings
        // by concatenating the length `n` strings with the alphabet members.
        loop<{S*}>{ "" }((g) =>
                {
                    for (c in a)
                        for (p in g)
                            p + "``c``"
                }));

    // This is a (variable) iterable of currently running machines.
    // Initially empty.
    l {M*} r = {};

    // iterate over all programs ...
    for(p in s) {
        // Create a machine with program `p`, include it
        //  in the list of running machines.
        //
        // We use a sequence constructor here instead of
        //  an iterable one (i.e. `r = {M(p, *r)}` to prevent
        // a stack overflow when accessing the deeply nested
        // lazy iterable.
        r = [M(p), *r];
        // iterate over all running machines ...
        for(e in r) {
            try {
                // run a step in machine e.
                e.p();
            } catch(x) {
                // exception means the machine halted.
                // print the program
                print(x.message);
                // remove the machine from the list for further execution
                r = r.filter(not(e.equals));
            }
        }
        // print(r.last);
    }
}

2

แคลคูลัสของ SK combinatorในHaskellขนาด 249 ไบต์

data C=H|S|K|C:$C deriving(Eq,Show)
n(a:$b)=m a*n b
n a=m a
m S=1
m K=1
m(S:$a)=n a
m _=0
f H=[S,K,S:$H,K:$H,S:$H:$H]
f a=[S:$b:$c:$d|b:$d:$(c:$e)<-[a],d==e,n b*n c*n d>0]++[K:$a:$H|n a>0]++do b:$c<-[a];[d:$c|d<-f b]++[b:$d|n b>0,d<-f c]
l=H:(f=<<l)

ลองออนไลน์!

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

กฎการประเมินมูลค่าการโทรตามค่าสำหรับแคลคูลัสของ SK combinator มีดังนี้:

(a) S xyzxz ( yz ) สำหรับx , y , zในรูปแบบปกติ
(b) K xyxสำหรับx , yในรูปแบบปกติ
(c) xyxyถ้าxx ′;
(d) xyxy ′สำหรับxในรูปแบบปกติถ้าyy′ Y'

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

(a) S xyzxz ( yz ) สำหรับx , y , zในรูปแบบปกติ
(b ′) K x H ↦ xสำหรับxในรูปแบบปกติ
(c) xyxyถ้าxx ′;
(d) xyxy ′สำหรับxในรูปแบบปกติถ้าyy′ ;
(e) S ↦ H;
(f) K ↦ H;
(g) SH ↦ H;
(h) KH ↦ H;
(i) SHH ↦ H.

เราถือว่าแอปพลิเคชัน H xใด ๆเป็นข้อผิดพลาดในการทำงานที่จะได้รับการจัดการเสมือนว่าเป็นลูปที่ไม่สิ้นสุด ละเว้น (ระดับบนสุด K x ☐ใด ๆ ละเว้นK☐ใด ๆ ละเว้น S x ☐สำหรับxในรูปแบบปกติ S normalH ที่ถูกละเว้นใด ๆ ) วิธีนี้เราจะไม่ส่งผลต่อพฤติกรรมการหยุดชะงักของคำศัพท์ปกติที่ขาดเอช

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

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

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