ลอจิกดิจิตอลแบบอิงกริด


33

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

ตัวอย่างเช่นหาก#แสดงถึงไพ่ทั่วไปเอาต์พุตที่ถูกต้องRคือฟังก์ชันfของอินพุตTและLและเอาต์พุตล่างBเป็นฟังก์ชันอื่นgของTและL:

 T
L#R         R = f(T, L)
 B          B = g(T, L)

(ไพ่เหล่านั้นเรียกว่า "duo" เนื่องจากมีสองฟังก์ชันและ "dyadic" เนื่องจากทั้งสองฟังก์ชันมีสองอาร์กิวเมนต์ )

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

 AB         D = f(f(A, C), B)
C##D        E = g(A, C)
 EF         F = g(f(A, C), B)

คุณสามารถจินตนาการได้ว่าเมื่อได้รับแผ่นกระเบื้อง duodyadic แต่ละชุดที่มีฟังก์ชั่นเฉพาะสามารถสร้างองค์ประกอบที่ซับซ้อน (และอาจมีประโยชน์)

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

อักขระไทล์และความสัมพันธ์อินพุต - เอาท์พุตมีดังนี้:
( Tสำหรับอินพุตสูงสุด, Lสำหรับอินพุตซ้าย, Rสำหรับเอาต์พุตขวา, Bสำหรับเอาต์พุตล่าง)

  1. ศูนย์: 0หรือ(ช่องว่าง) → R = 0,B = 0
  2. หนึ่ง: 1R = 1,B = 1
  3. ข้าม: +R = L,B = T
  4. กระจก: \R = T,B = L
  5. บนสุดเท่านั้น: UR = T,B = T
  6. เหลือเพียง: )R = L,B = L
  7. ไม่!R = not L,B = not T
  8. และ: &R = L and T,B = L and T
  9. หรือ: |R = L or T,B = L or T
  10. Xor: ^R = L xor T,B = L xor T

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้ในตารางสี่เหลี่ยมของตัวอักษร0 1+\U)!&|^ที่แสดงถึง "วงจร" ที่สร้างขึ้นโดยใช้แผ่นกระเบื้อง duodyadic ที่ใช้ตรรกะสิบตัว คุณต้องใช้สองสายของ0's และ1' s; หนึ่งจะเป็นคอลัมน์อินพุตด้านซ้ายและหนึ่งจะเป็นแถวอินพุตด้านบน โปรแกรม / ฟังก์ชั่นของคุณจำเป็นต้องพิมพ์ / ส่งคืนแถวเอาต์พุตด้านล่างและคอลัมน์เอาท์พุทขวา (รวมอยู่ใน0's และ1' s)

ตัวอย่างเช่นในตารางนี้

+++
+++

อินพุตทั้งหมดไหลตรงข้ามตารางไปยังเอาต์พุต

 ABC
D+++D
E+++E
 ABC

ดังนั้นอินพุต010/ 01จะมีเอาต์พุต010/ 01:

 010
0+++0
1+++1
 010

ผลลัพธ์ที่แน่นอนของโปรแกรมของคุณจะเป็น[bottom output row]\n[right output column]หรือ[bottom output row]/[right output column]:

010
01

หรือ

010/01

หากคุณเขียนฟังก์ชันคุณสามารถส่งคืนสองสายใน tuple หรือรายการ (หรือยังพิมพ์ได้)

รายละเอียด

  • ใช้สามอินพุตเป็นสตริงในลักษณะที่สมเหตุสมผล (โดยเฉพาะอย่างยิ่งในตารางคำสั่งแถวบนสุดคอลัมน์ซ้าย): บรรทัดคำสั่งไฟล์ข้อความ sdtin ฟังก์ชัน arg
  • คุณสามารถสันนิษฐานได้ว่าความยาวของแถวและคอลัมน์ที่ป้อนเข้านั้นจะตรงกับขนาดของกริดและจะประกอบด้วย0's และ1' s เท่านั้น
  • กริดของคุณต้องใช้อักขระที่เหมาะสม ( 0 1+\U)!&|^) จำไว้0และหมายถึงสิ่งเดียวกัน

กรณีทดสอบ

(อ่าน I / O เป็นtop/ leftbottom/ right.)

Nand:

&!

00/ 001/ 1
00/ 101/ 1
10/ 001/ 1
10/ 111/0

ทุกคน:

1111
1\+\
1+\+
1\+\

ป้อนข้อมูลใด ๆ จะส่งผล/11111111

Xor จาก Nand: (บันทึกคอลัมน์ของช่องว่างต่อท้าย)

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/ 0000000000/ 00000
00000/ 1000000010/ 00000
10000/ 0000000010/ 00000
10000/ 1000000000/00000

ซิกแซก:

+++\00000000
000\!!!!\000
00000000\+++

บิตแรกของอินพุตซ้ายกลายเป็นบิตสุดท้ายของเอาต์พุตขวา 0ทุกสิ่งทุกอย่างเป็น

000000000000/ 000000000000000/ 000
000000000000/ / 100000000000000/001

การขยายพันธุ์:

)))
UUU
U+U
U+U
UUU

บิตแรกของอินพุตซ้ายไปที่เอาต์พุตทั้งหมด

000/ 00000000/ 00000
000/ / 10000111/11111

นี่คือ pastebin ของกล่องทดสอบกริด 1 × 1 ทั้งหมด

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

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

โบนัส: คุณสามารถสร้าง "วงจร" ที่ยอดเยี่ยมได้อย่างไร

ป.ล. อย่าไปรบกวน "กระเบื้องดูโอเดียด" ของ Googling ฉันสร้างมันขึ้นมาเมื่อวานนี้ D
หากคุณต้องการพูดคุยเกี่ยวกับการขยายความคิดนี้เป็นภาษาโปรแกรมเต็มรูปแบบมาที่ห้องแชทนี้


11
+1 สำหรับความท้าทายที่ยอดเยี่ยม แต่ก็เป็นเพราะคุณได้ประดิษฐ์ไพ่สองใบซึ่งเป็นสิ่งที่เจ๋งมาก
Alex A.

3
+1 จริงๆมันจะไม่ได้ผลอย่างสมบูรณ์เพื่อ google นี้: goo.gl/zuqfdW ท้าทายมาก!
BrainSteel

ฉันอยู่กับพวกเขา ฉันสนใจกระเบื้องของคุณในฐานะภาษาการเขียนโปรแกรมมากกว่าในการแข่งขันกอล์ฟโดยเฉพาะ ป.ล. : มีกระเบื้องที่เป็นไปได้ 16 อันดังนั้นการขึ้นมาด้วยตัวอักษร / ชื่อสำหรับอีกหกอันนั้นจะเรียบร้อย
Sparr

มันน่าสนใจที่จะมีบล็อกที่เอาต์พุต / อินพุตจากทิศทางต่าง ๆ เพราะมิฉะนั้นคุณจะไม่สามารถสลักได้เพราะทุกอย่างไหลไปในทิศทางที่ถูกต้อง
Sp3000

2
คุณสามารถเปลี่ยน T / B เป็น U (p) / D (ของตัวเอง) เพื่อให้เราสามารถมี F / B ในลักษณะที่คล้ายคลึงกับสัญกรณ์คิวบ์รูบิคแล้ว . . tritriadic cubes?
Soham Chowdhury

คำตอบ:


8

Pyth, 122

ชนิดของสัตว์ประหลาด ใช้การเรียกซ้ำแบบง่าย ๆ ไม่มีอะไรแฟนซีเหมือนกับการเขียนโปรแกรมแบบไดนามิก

D:NGHR@Cm+d[1HG&GH|GHxGH0),[GH!G)[HG!H)x"+\\!1U)&|^"N#aYw)M:@@YGH?hgGtHHv@eYG?egtGHGv@ePYHjkm+0egtleYklePYjkm+0hgbtlePYleY

สาธิตออนไลน์

อินพุตมีวิธีดังต่อไปนี้: แรกกริด (ไม่มีการหลบหนีไม่มีสัญลักษณ์พิเศษ) จากนั้นอินพุตสองบรรทัดเช่น (ซิกแซก)

+++\00000000
000\!!!!\000
00000000\+++
000000000000
100

8

Mathematica, 331 276 270 267 264 262 252 250 ไบต์

Print@@@{#[[2;;,-1,2]],#[[-1,2;;,1]]}&@MapIndexed[h=Characters;({r@#2,b@#2}=<|##|>&@@Thread[h@"0 1+\\)U!&|^"->{0,0,1,i={##},{#2,#},##,1-i,1##,Max@i,(#-#2)^2}]&[r[#2-{1,0}],b[#2-{0,1}]]@#{1,1})&,Join[h@{"0"<>#3},h@StringSplit[#2<>"
"<>#,"
"]],{2}]&

นี่คือตัวละคร Unicode ที่ใช้งานส่วนตัวซึ่ง Mathematica ใช้เป็นตัวยกTเช่นเป็นตัวดำเนินการขนย้าย

นี่คือรุ่นที่อ่านได้มากขึ้น:

Print @@@ {#[[2 ;;, -1, 2]], #[[-1, 2 ;;, 1]]} &@
  MapIndexed[h = Characters;
   (
     {r@#2, b@#2} = <|##|> & @@ Thread[
            h@"0 1+\\)U!&|^" -> {
              0,
              0,
              1,
              i = {##},
              {#2, #},
              ##,
              1 - i,
              1 ##,
              Max@i,
              (# - #2)^2
              }] & [
          r[#2 - {1, 0}],
          b[#2 - {0, 1}]
          ] @ # {1, 1}
     ) &,
   Join[
    h@{"0" <> #3},
    h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
   ],
   {2}] &

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

คำอธิบาย

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

การประมวลผลอินพุต

นั่นคือบิตนี้:

Join[
  h@{"0" <> #3},
  h@StringSplit[#2 <> "\n" <> #, "\n"]\[Transpose]
]

นี่แค่แยกตารางออกเป็นรายการอักขระที่ซ้อนกัน (โปรดทราบว่าฉันกำหนดhเป็นนามแฝงสำหรับCharacterบางแห่งในรหัส) จากนั้นใส่แถวและคอลัมน์ด้วยอินพุต วิธีนี้ใช้งานได้เพราะ1และ0เป็นชื่อของไทล์ฟังก์ชันคงที่ดังนั้นการวางไว้บนนั้นจะมีผลเหมือนกับการป้อนอินพุตด้วยตนเอง เนื่องจากสิ่งเหล่านี้เป็นฟังก์ชั่นพวกเขาในทางเทคนิคจะรับอินพุตจากภายนอกกริด แต่เนื่องจากเป็นฟังก์ชันคงที่ที่ไม่สำคัญ มุมบนซ้ายจะได้รับ0แต่ก็ค่อนข้างจะเป็นกฎเกณฑ์เนื่องจากผลลัพธ์ของกระเบื้องนั้นไม่เคยถูกใช้

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

การแก้ปัญหากริด

(ส่วนนี้ล้าสมัยเล็กน้อยจะแก้ไขเมื่อฉันแน่ใจว่าฉันเล่นกอล์ฟเสร็จแล้ว)

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

เราใช้ตัวแปรr(ight) และb(ottom) เป็นตารางการค้นหาสำหรับผลลัพธ์ของแต่ละเซลล์ ฟังก์ชั่นไม่ระบุชื่อของเรามีพิกัดปัจจุบัน#2ดังนั้นเราจึงได้รับอินพุตไปยังเซลล์ใด ๆ ด้วย

r[#2 - {1, 0}],
b[#2 - {0, 1}]

โปรดทราบว่าในแถวแรกและคอลัมน์การเข้าถึงนี้จะไม่ได้กำหนดค่าและr bMathematica ไม่มีปัญหากับสิ่งนั้นและจะให้ค่าพิกัดกลับมา แต่เราจะทิ้งผลลัพธ์นี้ต่อไปเนื่องจากไทล์ทั้งหมดในแถว / คอลัมน์นั้นเป็นฟังก์ชันคงที่

ตอนนี้สิ่งนี้:

<|##|> & @@ Thread[
  h@"0 1+\\U)!&|^" -> {
     z = {0, 0}, z, o = 1 + z, {##}, ...
  }] &

เป็นรูปแบบ golfed ของ

<|"0" -> (z = {0, 0}), " " -> z, "1" -> (o = 1 + z), "+" -> {##}, ... |> &

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

  • 0: ตรงไปตรงมาเราเพิ่งคืนค่าคงที่{0, 0}และกำหนดสิ่งนี้ให้กับzการใช้ในอนาคต (เช่นในไทล์สเปซ)
  • 1: เป็นหลักเพียง{1,1}แต่ต้องนี้จะลงไปz 1+zนอกจากนี้เรายังบันทึกสิ่งนี้ไว้oด้วยเพราะมันจะมีประโยชน์สำหรับกระเบื้องทั้งหมดที่มีเอาต์พุตเหมือนกัน
  • +: ที่นี่เราใช้ประโยชน์จากลำดับ {##}เหมือนกับ{#,#2}และส่งผ่านอินพุตทั้งสองผ่านไม่เปลี่ยนแปลง
  • \: เราสลับสองข้อโต้แย้ง, {#2,#}.
  • U: oตอนนี้เราสามารถทำให้การใช้งานของ o#2หมายความว่า{1,1}*#2เราแค่ใส่อาร์กิวเมนต์บนลงในเอาต์พุตทั้งสอง
  • ): Analogously o#สำหรับอาร์กิวเมนต์ด้านซ้าย:
  • !: Bitwise ไม่เป็นที่น่ารำคาญในมาติกา แต่เนื่องจากเราเท่านั้นที่เคยมี0และ1เราก็สามารถลบปัจจัยการผลิตทั้งจาก1(จึง inverting พวกเขา) 1-{##}และผ่านพวกเขา:
  • &: อันนี้ค่อนข้างดี ก่อนอื่นเราสังเกตว่า bitwise และ for 0และ1เหมือนกับการคูณ นอกจากนี้เป็นเช่นเดียวกับo##o*#*#2
  • |: อีกครั้งเราใช้ฟังก์ชั่นที่เทียบเท่า Bitwise หรือเหมือนกับMaxในกรณีนี้ดังนั้นเราใช้Maxกับอาร์กิวเมนต์ที่ป้อนเข้าและคูณผลลัพธ์เข้า{1,1}ด้วยกัน
  • ^การที่สั้นที่สุดที่ผมเคยพบ xor คือการใช้ความแตกต่างและไอทีสแควร์ (เพื่อให้แน่ใจว่า positivity) o(#-#2)^2ดังนั้นเราจึงได้มี

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

การประมวลผลเอาท์พุท

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

#[[2;;,-1,2]]

และเอาต์พุตสุดท้ายของคอลัมน์สุดท้ายด้วย

#[[-1,2;;,1]]

โปรดทราบว่า2;;เป็นช่วงจากองค์ประกอบที่สองถึงองค์ประกอบสุดท้าย

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


8

C, 332 309 272 270 266 259 247 225 ไบต์

#define C(x)*c-x?
i,k,T,L,m;f(c,t,l)char*c,*t,*l;{while(L=l[i]){for(k=0;T=t[k];c++)L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),t[k++]=T;c++;l[i++]=L;}}

ดูผลลัพธ์ออนไลน์ได้ที่นี่!

สิ่งนี้กำหนดฟังก์ชั่นvoid f(char*, char*, char*)ซึ่งควรใช้บอร์ดเป็นอินพุตแรกจากนั้นแถวบนสุดของอินพุตและจากนั้นแถวซ้ายของอินพุต

นี่คือสิ่งที่ฉันใช้ทดสอบ:

#include "stdio.h"
int main() {
    char buf[1024],top[33],left[33];
    /* Copy and paste an example circuit as the first input,
       and put a 'Q' immediately after it. 
       Note that the Q is never touched by the function f, and is used
       solely as a delimiter for input. */
    scanf("%[^Q]Q ",buf);
    /* Then enter your top inputs */
    scanf("%[01]%*[^01]", top);
    /* Then your left ones */
    scanf("%[01]", left);
    /* OUTPUT: Bottom\nRight */
    f(buf, top, left);
    return 0;
}

ดังนั้นโดยการป้อนตัวคูณแบบ 2 บิตของ Sp3000:

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUUQ
11110000
00000000

เราได้รับ:

00001001
11111111

ในบันทึกอื่นด้วย SP3000 ครึ่งงูพิษที่อยู่ในใจผมอยากจะเห็นงูเต็ม ... หนึ่งของพวกคุณไม่ได้! ฉันไม่คิดว่าระบบจะยืนเป็นของตัวเองเป็นภาษาการเขียนโปรแกรม แต่มันน่าสนใจมาก นี่เป็นเป้าหมายที่ยอดเยี่ยมสำหรับ metagolf!

คำอธิบายสั้น ๆ :

นี่คือรหัสที่ไม่ได้ลงนามและแสดงความคิดเห็น:

/* We define the first half of the ?: conditional operator because, well,
   it appears over and over again. */
#define C(x)*c-x?
/* i,k are counting variables
   T,L are *current* top and left inputs */
i,k,T,L,m;
f(c,t,l)char*c,*t,*l;{
    /* The outer loop iterates from top to bottom over l and c */
    while(L=l[i]){
        /* Inner loop iterates from left to right over t and c */
        for(k=0;T=t[k];c++)
            /* This line looks awful, but it's just a bunch of character
            comparisons, and sets T and L to the output of the current c */
            L=C(49)C(43)C(92)C(85)C(41)C(33)C(38)C('|')C(94)T=48:(T^=L-48):(T|=L):(T&=L):(T^=1,L^1):(T=L):T:(m=T,T=L,m):L:(T=49),
            /* Write our output to our input, it will be used for the next row */
            t[k++]=T;
        c++; /*Absorbs the newline at the end of every row */
        /* Keep track of our right-most outputs, 
        and store them in the handy string passed to the function. */
        l[i++]=L;
    }
    /* Bottom output is now stored entirely in t, as is right output in l */        
}

เราวนซ้ำไปมาcจากซ้ายไปขวา (จากบนลงล่าง) เขียนใหม่tอินพุตทุกครั้งและผลักเอาท์พุทขวาสุดที่ถูกผลักเข้าไปlสตริง เราสามารถจินตนาการสิ่งนี้เป็นการแทนที่แถวบนสุดcด้วย1's และ0' iteratively และติดตามบิตที่ผลักออกทางด้านขวา

นี่คือลำดับภาพที่เห็นได้ชัดเจนขึ้นทีละแถว:

 111                                  
1&+^  =>  110 ->0  =>     ->0  =>     0 Thus, "01" has been written to l,
1+&+     1+&+         110 ->1         1
                                  110   And "110" is stored currently in t.

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


ศักยภาพมากมายสำหรับการเล่นกอล์ฟ! เริ่มต้นด้วยการเปลี่ยนส่วนหัวของfเป็นf(c,t,l)char*c,*t,*l(ไม่ให้อึเกี่ยวกับประเภทส่งคืน)
FUZxxl

@FUZxxl มีคนพูดถึงเรื่องนี้ในการแชท แต่ฉันไม่สามารถทำงานได้ พฤติกรรมนี้เป็นมาตรฐานหรือไม่ LLVM ส่งข้อผิดพลาดอย่างน้อย 2 ข้อกับบรรทัดนั้น
BrainSteel

ขอโทษ f(c,t,l)char*c,*t,*l;ควรจะได้รับ อย่าคอมไพล์ในโหมด C11 เนื่องจากกฎ int โดยนัยซึ่งทำให้เราสามารถดรอปชนิดส่งคืนได้ถูกดร็อปในการแก้ไขนั้น
FUZxxl

@FUZxxl ดูเหมือนว่าจะล้มเหลวใน C99 เช่นกัน ในความเป็นจริงทุกโหมดที่ฉันได้ตั้งค่าคอมไพเลอร์ได้ปฏิเสธรหัสนั้น
BrainSteel

คุณเพิ่มเครื่องหมายอัฒภาคแล้ว*lใช่ไหม มันรวบรวมในโหมด C99 บนเครื่องของฉัน
FUZxxl

7

Python 2, 316 ไบต์

ฟังก์ชั่นนี้สร้างฟังก์ชั่นแลมบ์ดาไทล์ 10 รายการจากนั้นทำซ้ำผ่านกริดโดยอัพเดตสถานะลอจิก สถานะลอจิกแนวตั้งและแนวนอนสุดท้ายจะถูกพิมพ์

def b(d,j,g):
 h=enumerate;e=dict((s[0],eval('lambda T,L:('+s[1:]+')'))for s in' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));j=list(j+'\n');g=list(g)
 for y,k in h(d.split('\n')):
  L=g[y]
  for x,c in h(k):T=j[x];L,B=e[c](int(T),int(L));j[x]=`B`
  g[y]=`L`
 print''.join(j+g)

รหัส ungolfed รวมถึงการทดสอบ:

def logic(grid, top, left):
    loop = enumerate;
    func = dict((s[0], eval('lambda T,L:('+s[1:]+')')) for s in ' 0,0#00,0#11,1#+L,T#\\T,L#UT,T#)L,L#!1-L,1-T#&T&L,T&L#|T|L,T|L#^T^L,T^L'.split('#'));
    top = list(top+'\n');
    left = list(left)
    for y,row in loop(grid.split('\n')):
        L = left[y]
        for x,cell in loop(row) :
            T = top[x];
            L, B = func[cell](int(T), int(L));
            top[x] = `B`
        left[y] = `L`
    print ''.join(top + left)

import re
testset = open('test.txt', 'rt').read().strip()
for test in testset.split('\n\n'):
    if test.endswith(':'):
        print '------------------\n'+test
    elif re.match('^[01/\n]+$', test, re.S):
        for run in test.split():
            top, left = run.split('/')
            print 'test', top, left
            logic(grid, top, left)
    else:
        grid = test

test.txtไฟล์ (รวมทั้ง 2 การทดสอบอื่น ๆ โดย SP3000):

Nand:

&!

00/0
00/1
10/0
10/1

All ones:

1111
1\+\
1+\+
1\+\

1001/1100

Xor from Nand (note the column of trailing spaces):

\)+\ 
U&!& 
+! ! 
\&!& 
   ! 

00000/00000
00000/10000
10000/00000
10000/10000

Half adder:

+))
U&+
U+^

000/000
000/100
100/000
100/100

Right shift:

\\\
\++
\++

001/110
010/101
101/100

ผลการทดสอบ:

------------------
Nand:
test 00 0
01
1
test 00 1
01
1
test 10 0
01
1
test 10 1
11
0
------------------
All ones:
test 1001 1100
1111
1111
------------------
Xor from Nand (note the column of trailing spaces):
test 00000 00000
00000
00000
test 00000 10000
00010
00000
test 10000 00000
00010
00000
test 10000 10000
00000
00000
------------------
Half adder:
test 000 000
000
000
test 000 100
001
101
test 100 000
101
001
test 100 100
110
110
------------------
Right shift:
test 001 110
000
111
test 010 101
101
010
test 101 100
010
110

7

Python 2, 384 338 325 bytes

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))

CH อย่างจริงจังหากนี่ไม่ใช่ของเล่นแล้วคุณควรเริ่มส่งเสียงเรียกโรงงานของเล่นบางแห่ง

ตอนนี้เล่นกอล์ฟได้มากขึ้นและมีประสิทธิภาพน้อยลง แต่ยังไม่ทันถึง CarpetPython ใส่เหมือนf("1111\n1\\+\\\n1+\\+\n1\\+\\","0101","1010")เอาต์พุตเป็น tuple ของสองสตริง ตรวจสอบให้แน่ใจว่ากระดานไม่มีบรรทัดใหม่ที่ต่อท้ายซึ่งจะทำลายสิ่งต่าง ๆ

โปรแกรมทดสอบ

def f(G,T,L):
 def g(x,y):
  if x>-1<y:l=g(x-1,y)[1];t=g(x,y-1)[0];r=l,t,1-l,0,0,1,t,l,l&t,l|t,l^t;i="+\\!0 1U)&|^".index(G[y*-~W+x]);return((t,l,1-t)+r[3:])[i],r[i]
  return(int((y<0)*T[x]or L[y]),)*2
 H=G.count("\n")+1;W=len(G)/H;return eval('"".join(map(str,[g(%s]for _ in range(%s)])),'*2%('_,H-1)[0','W','W-1,_)[1','H'))


import itertools

G = r"""
+))
U&+
U+^
""".strip("\n")

def test(T, L):
    print f(G, T, L)

def test_all():
    W = len(G[0])
    H = len(G)

    for T in itertools.product([0, 1], repeat=len(G.split("\n")[0])):
        T = "".join(map(str, T))

        for L in itertools.product([0, 1], repeat=len(G.split("\n"))):
            L = "".join(map(str, L))

            print "[T = %s; L = %s]" % (T, L)
            test(T, L)
            print ""

test("000", "000")
test("000", "100")
test("100", "000")
test("100", "100")

คุณสามารถทดสอบกรณีที่เป็นไปได้ทั้งหมดด้วย test_all()นอกจากนี้คุณยังสามารถทดสอบกรณีที่เป็นไปได้ทั้งหมดที่มี

กรณีทดสอบพิเศษ

บวกครึ่ง

นี่คือ adder ครึ่งหนึ่งซึ่งเพิ่มบิตซ้ายบนเอาท์พุท<input bit> <carry> <sum>:

+))
U&+
U+^

แบบทดสอบ:

000 / 000  ->  000 / 000
000 / 100  ->  001 / 101
100 / 000  ->  101 / 001
100 / 100  ->  110 / 110

เอาต์พุตควรเหมือนกันแม้ว่าบิตที่สอง / สามของอินพุตจะเปลี่ยนไป

เลื่อนไปทางขวา

รับabc / defผลนี้fab / cde:

\\\
\++
\++

แบบทดสอบ:

001 / 110 -> 000 / 111
010 / 101 -> 101 / 010
101 / 100 -> 010 / 110

ตัวเรียงลำดับ 3 บิต

เรียงลำดับสามบิตแรกของด้านบนลงในสามบิตสุดท้ายของด้านล่าง เอาต์พุตที่ถูกต้องคือขยะ

UUU)))
UU)U U
U&UU U
U+|&)U
\UU++|
 \)&UU
  \+|U
   UUU

แบบทดสอบ:

000000 / 00000000 -> 000000 / 00000000
001000 / 00000000 -> 000001 / 11111111
010000 / 00000000 -> 000001 / 00001111
011000 / 00000000 -> 000011 / 11111111
100000 / 00000000 -> 000001 / 00001111
101000 / 00000000 -> 000011 / 11111111
110000 / 00000000 -> 000011 / 00001111
111000 / 00000000 -> 000111 / 11111111

ตัวคูณทวีคูณ 2 บิต

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

UUUU))))
UU++)))&
UUU+)  U
UU++&))U
U++&+)^U
U)&\&)UU
   U+^UU
   \&UUU

แก้ไข: แสดงคอลัมน์และแถวสองแถว

แบบทดสอบ:

00000000 / 00000000 -> 00000000 / 00000000
00010000 / 00000000 -> 00000000 / 10000000
00100000 / 00000000 -> 00000000 / 00000000
00110000 / 00000000 -> 00000000 / 10000000
01000000 / 00000000 -> 00000000 / 00000000
01010000 / 00000000 -> 00000001 / 11111111
01100000 / 00000000 -> 00000010 / 00000000
01110000 / 00000000 -> 00000011 / 11111111
10000000 / 00000000 -> 00000000 / 00000000
10010000 / 00000000 -> 00000010 / 10000000
10100000 / 00000000 -> 00000100 / 00000000
10110000 / 00000000 -> 00000110 / 10000000
11000000 / 00000000 -> 00000000 / 00000000
11010000 / 00000000 -> 00000011 / 11111111
11100000 / 00000000 -> 00000110 / 00000000
11110000 / 00000000 -> 00001001 / 11111111

1

R, 524 517

อาจมีหลายห้องที่สามารถลดสิ่งนี้ได้ในขณะนี้ แต่สิ่งนี้น่าสนใจจริงๆ มีสองฟังก์ชั่น ฟังก์ชั่น d เป็นผู้ปฏิบัติงานและ f เป็นผู้เปรียบเทียบ

ฟังก์ชัน d ถูกเรียกด้วย 3 สาย, เกต, ด้านบนและด้านซ้าย ประตูถูกใส่เข้าไปในเมทริกซ์ซึ่งพิจารณาจากความกว้าง

I=strtoi;S=strsplit;m=matrix;f=function(L,T,G){O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));X=which(S(' 01+\\U)!&|^','')[[1]]==G);M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);return(c(O[M[2,X]],O[M[3,X]]))};d=function(G,U,L){W=nchar(U);H=nchar(L);U=c(list(I(S(U,'')[[1]])),rep(NA,H));L=c(list(I(S(L,'')[[1]])),rep(NA,W));G=m((S(G,'')[[1]]),nrow=W);for(i in 1:H)for(n in 1:W){X=f(L[[n]][i],U[[i]][n],G[n,i]);L[[n+1]][i]=X[1];U[[i+1]][n]=X[2]};cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)}

ฟอร์แมตเล็กน้อย

I=strtoi;S=strsplit;m=matrix;
f=function(L,T,G){
    O=I(c(0,1,L,T,!L,!T,L&T,L|T,xor(L,T)));
    X=which(S(' 01+\\U)!&|^','')[[1]]==G);
    M=m(c(1,1,1,2,1,1,3,2,2,4,3,4,5,4,3,6,4,4,7,3,3,8,5,6,9,7,7,10,8,8,11,9,9),nrow=3);
    return(c(O[M[2,X]],O[M[3,X]]))
};
d=function(G,U,L){
    W=nchar(U);H=nchar(L);
    U=c(list(I(S(U,'')[[1]])),rep(NA,H));
    L=c(list(I(S(L,'')[[1]])),rep(NA,W));
    G=m((S(G,'')[[1]]),nrow=W);
    for(i in 1:H)
        for(n in 1:W){
            X=f(L[[n]][i],U[[i]][n],G[n,i]);
            L[[n+1]][i]=X[1];
            U[[i+1]][n]=X[2]
        };
    cat(U[[H+1]],' / ',L[[W+1]],sep='',fill=T)
}

การทดสอบบางอย่าง

> d('&!','00','0')
01 / 1
> d('&!','00','1')
01 / 1
> d('&!','10','0')
01 / 1
> d('&!','10','1')
11 / 0
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','00000')
00000 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','00000','10000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','00000')
00010 / 00000
> d('\\)+\\ U&!& +! ! \\&!&    ! ','10000','10000')
00000 / 00000
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','100')
000000000000 / 001
> d('+++\\00000000000\\!!!!\\00000000000\\+++','000000000000','000')
000000000000 / 000
> d('+))U&+U+^','000','000')
000 / 000
> d('+))U&+U+^','000','100')
001 / 101
> d('+))U&+U+^','100','000')
101 / 001
> d('+))U&+U+^','100','100')
110 / 110
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.