ให้ตารางความจริงเอาท์พุทโปรแกรม Stackylogic ที่ตรงกับมัน


17

Stackylogic เป็นภาษาโปรแกรมที่ผมทำขึ้นมาในความท้าทายที่ก่อนหน้านี้: Run Stackylogic อ่านโพสต์นั้นสำหรับรายละเอียดและตัวอย่างทั้งหมด แต่นี่คือวิธีการถอดความ:

Stackylogic ใช้0's และ1' s สำหรับอินพุตและเอาต์พุตเดี่ยว0 หรือ1เมื่อเสร็จสมบูรณ์

โปรแกรมประกอบด้วยบรรทัดที่มีเฉพาะอักขระ01?เช่นเดียวกับหนึ่ง<บรรทัดที่ส่วนท้ายของหนึ่งบรรทัด สายอาจจะไม่ว่างเปล่าและบรรทัดที่มี<จะต้องมีอย่างน้อยหนึ่ง0, 1หรือ ?ก่อนที่มันจะ

นี่คือตัวอย่างโปรแกรมที่คำนวณNANDของสองบิต:

1
?<
11
?
0

ทุกบรรทัดในโปรแกรมถือว่าเป็นสแต็กโดยมีด้านล่างทางด้านซ้ายและด้านบนทางด้านขวา โดยปริยายมีสแต็กเปล่า (เช่นบรรทัดว่าง) ก่อนบรรทัดแรกในโปรแกรมและหลังบรรทัดสุดท้าย

กระบวนการ<เรียกว่าเคอร์เซอร์ทำเครื่องหมายสแต็กเพื่อเริ่มต้นเมื่อโปรแกรมทำงาน การดำเนินการดังต่อไปนี้:

  1. วางอักขระบนสุดออกจากสแต็กที่เคอร์เซอร์กำลังชี้ไป

    • หากตัวละครนั้น?ให้แจ้งผู้ใช้สำหรับ0หรือหรือ1และทำราวกับว่าเป็นตัวละคร
    • หากอักขระอยู่0ให้เลื่อนเคอร์เซอร์ขึ้นหนึ่งกอง (ไปยังบรรทัดที่อยู่เหนือบรรทัดปัจจุบัน)
    • หากอักขระอยู่1ให้เลื่อนเคอร์เซอร์หนึ่งสแต็กลง (ไปยังบรรทัดด้านล่างบรรทัดปัจจุบัน)
  2. หากกองเคอร์เซอร์เลื่อนไปที่ว่างเปล่าเอาท์พุทค่าสุดท้ายที่โผล่ออกมาจากกอง (เสมอ0หรือหรือ1) และจบโปรแกรม

  3. มิฉะนั้นหากเคอร์เซอร์เลื่อนไปที่ไม่ว่างเปล่าให้กลับไปที่ขั้นตอนที่ 1 และทำซ้ำกระบวนการ

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

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

เคสฐาน

0 ตารางความจริงสองอินพุตคือตารางที่ส่งออก0หรือ 1เสมอ Stackylogic ที่เท่าเทียมกันของตารางเหล่านี้0<และ1< ตามลำดับ

ขั้นตอนอุปนัย

สมมติว่า Stackylogic สามารถจำลองตารางความจริง N-input ใด ๆ ก็ได้ ให้ M = N + 1

เอ็มป้อนข้อมูลตาราง, T, สามารถแสดงเป็นสองตาราง N-อินพุต T 0และ T 1แถมบีบิตการป้อนข้อมูลเพิ่มเติมเมื่อ B คือ 0, ผลมาจากการที่ T 0ถูกนำมาใช้ เมื่อ B คือ 1, ผลมาจากการที่ T 1ถูกนำมาใช้

ตัวอย่างเช่นตารางความจริงอินพุต 3 ที่สอดคล้องกับ pseudocode

if B:
    result = x OR y
else:
    result = x NAND y

คือ

B x y | result
0 0 0 | 1
0 0 1 | 1
0 1 0 | 1
0 1 1 | 0
1 0 0 | 0
1 0 1 | 1
1 1 0 | 1
1 1 1 | 1

ซึ่งจริงๆแล้วเป็นตารางความจริง 2 อินพุทสำหรับ NAND และ OR ซ้อนกันบน muxing bit B

ให้ S 0และ S 1เป็นโปรแกรม Stackylogic ที่เป็นไปตาม T 0และ T 1ตามลำดับ (เรารู้ว่าสิ่งเหล่านี้มีอยู่บนพื้นฐานของสมมติฐานแรก) โปรแกรม S ที่สร้างความพึงพอใจให้กับ T สามารถสร้างเป็น:

[lines of S0 excluding the cursor, with 0 appended to all lines below the cursor]
?<
[lines of S1 excluding the cursor, with 1 appended to all lines above the cursor]

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

ตัวอย่างเช่นโปรแกรม Stackylogic สำหรับ OR และ NAND ได้แก่

?
?<

และ

1
?<
11
?
0

สามารถรวมกันเพื่อจำลอง

if B:
    result = x OR y
else:
    result = x NAND y

ชอบมาก:

1
?
110
?0
00
0
?<
?1
?

ดังนั้นตารางความจริงใด ๆ สามารถจำลองโดยโปรแกรม Stackylogic

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่รับในตารางความจริงอินพุต N (N> 0) ในรูปแบบของรายการค่าบูลีน2 Nที่แสดงผลลัพธ์ของตารางตามลำดับเลขฐานสองจากน้อยไปมาก

รูปแบบอินพุตที่เหมาะสมไม่เป็นไร เช่นสำหรับตารางหรือความจริง

x y | OR
0 0 | 0
0 1 | 1
1 0 | 1
1 1 | 1

ลักษณะอินพุตใด ๆ เหล่านี้จะใช้ได้:

0111

0, 1, 1, 1

0
1
1
1

[False, True, True, True]

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

ตัวอย่างเช่นถ้าอินพุตเป็น11100111หนึ่งเอาต์พุตที่ถูกต้องจะเป็น

1
?
110
?0
00
0
?<
?1
?

แต่มีคนอื่นอีกมากมาย

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

ดูความท้าทาย Stackylogic ดั้งเดิมหากคุณต้องการล่าม


เราสามารถใช้ N เป็นอินพุตที่สองได้หรือไม่?
Leun Nun

@LeakyNun ใช่ (หรือ 2 ^ N) หากจำเป็น
งานอดิเรกของ Calvin

คำตอบ:


8

Pyth, 53 ไบต์

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<

ลองออนไลน์

นี่เป็นการใช้งานระบบที่อธิบายไว้ในความท้าทายสำหรับวิธีการใช้ตารางความจริงตามอำเภอใจใน Stackylogic เราตัดตารางความจริงออกเป็นครึ่ง ๆ ใช้มันซ้ำแล้วผนวก 0 และ 1 ตามความเหมาะสม

ฟังก์ชันนี้กำหนดฟังก์ชันเวียนเกิดซึ่งมีค่าส่งคืน[1, ['0', '?', '1']]โดยที่หมายเลขแรกคือตำแหน่งของตัวชี้และส่วนที่เหลือเป็นโปรแกรมซ้อน

L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hbjXF+yQ\<
                                                         Q = eval(input())
L?tb,lehJyMc2bsX0.e.e+W>_Wk-Yhb0ZkebJ\?,0]`hb
L                                                 def y(b): return
 ?tb                                              if b[1:] (base case on false)
                                      ,0]`hb      else: [0, str([0])]
                                                  then:
           c2b                                    Cut the input in half
         yM                                       Map y over the halves
        J                                         Store that in J
    ,leh                                          The cursor position is the length 
                                                  of the body of the first function
                 .e                 J             enum-map, where k is the index
                                                  and b is the value, over J
                   .e             eb              enum-map, Y is the index and
                                                  Z is the value, over body of b
                     +W         Zk                Add to Z (line) k (the overall 
                                                  index, 0 or 1) conditional on
                          -Yhb                    Y (line index) - cursor
                       _Wk                        Negated if k
                      >       0                   > 0
               X0                    \?           Add '?' to the first element
              s                                   Concatenate, giving the body

jXF+yQ\<
    yQ      Call the above on the input
   +  \<    Append a '<'
 XF         Splat the 3 element list into the 'append-at' function,
            adding the curson in the right place
j           Join on newlines and print.

อืม ... ฉันเพิ่งกลับบ้านกลับไปแก้ไขวิธีการแก้ปัญหาของฉัน ...
รั่วนูน

3

Python 3, 352 208 205 ไบต์

นี่ยังไม่อัปยศมากและฉันจะพยายามเพิ่มคำอธิบายในภายหลัง หลังจากแก้ไขบางอย่างฉันจัดการเพื่อลบ144 147 ไบต์

f=lambda x,l=len,r=range:'\n'.join(*x)if l(x)<2 else f([[x[i][j]+['0',''][j<=l(x[i])//2]for j in r(l(x[i]))]+[['?','?<'][l(x)<3]]+[x[i+1][j]+['1',''][j>=l(x[i])//2]for j in r(l(x[i]))]for i in r(0,l(x),2)])

ฟังก์ชั่นfที่รับอินพุตของค่าตารางความจริงเป็นรายการของบูลีนของแบบฟอร์ม['1','1','1','0','0','1'...]โดยที่'1'เป็นจริงและ'0'เป็นเท็จและส่งคืนโปรแกรม Stackylogic

ลองใช้กับ Ideone

หากคุณต้องการที่จะทดสอบโปรแกรมการผลิตคุณสามารถใช้GamrCorps 's นูนล่ามที่นี่

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

นี่เป็นฟังก์ชั่นวนซ้ำและใช้วิธีอุปนัยที่อธิบายไว้ในคำถาม

ที่ระดับการเรียกซ้ำที่ทำดัชนีเป็นศูนย์aฟังก์ชันจะสร้างn/2 a+1-input โปรแกรม Stackylogic จากโปรแกรม -input n aในรายการ สิ่งนี้ทำได้โดยการเข้าร่วมคู่ที่อยู่ติดกันทั้งหมดของสองโปรแกรมในรายการด้วย?; เนื่องจากเคอร์เซอร์อยู่ที่องค์ประกอบกลางของแต่ละโปรแกรมองค์ประกอบการต่อท้ายที่ต้องการ0หรือ1สามารถทำได้โดยวนซ้ำในแต่ละบรรทัดของโปรแกรมที่เข้าร่วมและผนวกถ้าดัชนีของบรรทัดปัจจุบันน้อยกว่าหรือเท่ากับ / มากกว่า มากกว่าหรือเท่ากับดัชนีกลางตามความเหมาะสม หากรายการมีเพียงสองโปรแกรมการเรียกซ้ำซ้ำครั้งต่อไปจะให้โปรแกรมสุดท้าย ?<ตั้งแต่นี้ต้องเคอร์เซอร์ร่วมแทนที่จะเกิดขึ้นบน

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

ตัวอย่างช่วยในการอธิบายสิ่งนี้:

Take the input ['1', '1', '1', '0', '0', '1', '1', '1'].

Level  Return value

0  [['1', '?', '1'], ['1', '?', '0'], ['0', '?', '1'], ['1', '?', '1']]
1  [['1', '?', '10', '?', '11', '?', '0'], ['0', '?', '10', '?', '11', '?', '1']]
2  [['1', '?', '10', '?', '110', '?0', '00', '?<', '01', '?1', '101', '?', '11', '?', '1']]
3  '1\n?\n10\n?\n110\n?0\n00\n?<\n01\n?1\n101\n?\n11\n?\n1'

which when printed gives:

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