เครื่องคิดเลขประตูตรรกะที่เรียบง่าย


9

ภารกิจของคุณถ้าคุณเลือกที่จะยอมรับมันก็คือการสร้างผู้ประเมินความจริงแบบง่าย ๆ สำหรับผู้ประกอบการเชิงตรรกะดังต่อไปนี้:

----------------------------------------------------------------------------------
  Logical Name          |  Gate Name   |  Symbol  |  Symbol Name  |  Truth Table
----------------------------------------------------------------------------------
  Identity              |  is          |          |  (none)       |  10
  Negation              |  not         |    ~     |  tilde        |  01
  Conjunction           |  and         |    &     |  ampersand    |  1000
  Disjunction           |  or          |    |     |  pipe         |  1110
  Negative Conjunction  |  nand        |    ^     |  caret        |  0111
  Joint Denial          |  nor         |    v     |  "vee"        |  0001
  Exclusive Disjunction |  xor         |    x     |  "ecks"       |  0110
  Equivalence           |  equals/xnor |    =     |  equals       |  1001
  Implication           |  implies     |    >     |  greater than |  1011

ตารางความจริงอยู่ในลำดับต่อไปนี้:

  1. 1 1
  2. 1 0
  3. 0 1
  4. 0 0

อินพุตจะมาในรูปแบบสตริง 0, 1 และสัญลักษณ์ คุณสามารถยอมรับอินพุตเป็นพารามิเตอร์หรืออ่านจากผู้ใช้บน stdin นี่คือตัวอย่างอินพุต / เอาท์พุตตัวอย่างบางส่วน:

Input: 1
Output: 1

Input: ~1
Output: 0

Input: 0|1
Output: 1

Input: 1>0
Output: 0

ตัวดำเนินการ unary (การปฏิเสธ) จะปรากฏขึ้นเสมอก่อนที่ค่าบูลีนในขณะที่ตัวดำเนินการไบนารีจะปรากฏระหว่างค่าบูลีนสองค่าเสมอ คุณสามารถสันนิษฐานได้ว่าการป้อนข้อมูลทั้งหมดจะถูกต้อง สตริงเป็นสตริง ASCII ปกติ

หากคุณต้องการคุณสามารถใช้ T และ F มากกว่า 1 และ 0. -6กับการนับตัวละครของคุณหากคุณสนับสนุนทั้งสอง

นี่คือ : รหัสที่สั้นที่สุดในทุกภาษาชนะ!


3
ฉันเชื่อว่า^ชื่อสัญลักษณ์ควรพูดว่าคาเร็
FireFly

3
@FireFly ฮ่าฮ่าคุณพูดถูก ใกล้อาหารกลางวันมากเกินไป! ขอบคุณ
asteri

คำตอบ:


6

APL (45 - 6 = 39)

⍎(1+9≠L)⌷¨↓⍉Z⍪⍉⍪'10∧∨⍲⍱≠≤*'[L←'TF&|^vx>'⍳Z←⍞]

รองรับTและFเป็น input แต่มักจะส่งออกหรือ01

คำอธิบาย:

  • Z←⍞: อ่านบรรทัดและเก็บไว้ใน Z
  • L←'TF&|^vx>'⍳Z: ได้รับดัชนีใน'TF&|^vx>'ตัวละครในแต่ละZให้ถ้าตัวละครไม่ได้อยู่ใน9'TF&|^vx>'
  • '10∧∨⍲⍱≠≤*'[... ]: '10∧∨⍲⍱≠≤*'หาตัวอักษรที่สอดคล้องกันใน (ดังนั้นตัวละครที่ไม่ได้อยู่ในรายการแรกจะกลายเป็น*)
  • ↓⍉Z⍪⍉⍪: ทำให้นี่เป็นเมทริกซ์วางต้นฉบับ ( Z) ด้านบนของมันแล้วแยกมันออกเป็นรายการของสตริงโดยที่อักขระตัวแรกคือตัวอักษรดั้งเดิมและตัวที่สองคือการแปลถ้ามี
  • (1+9≠L)⌷¨: สำหรับแต่ละสตริงเหล่านี้รับตัวอักษรตัวแรกถ้าไม่มีการแปล (ถ้าL=9อยู่ในที่นั้น) และตัวที่สองถ้ามี
  • ตัวอย่าง: ถ้าอินพุตT|0เราจะได้1∨0ตอนนี้ซึ่งเป็นนิพจน์ APL ที่สอดคล้องกัน
  • : eval

หมายเหตุ: ~และ=ทำสิ่งที่ถูกต้องเพื่อให้พวกเขาไม่จำเป็นต้องถูกแทนที่ด้วยอะไร


ดีมาก! นี่เป็นวิธีการแปลเป็น APL และ Eval ใช่มั้ย ฉันไตร่ตรองถึงวิธีการแบบ gerund-based ใน J แต่ฉันไม่รู้วิธีแยกตัวถูกดำเนินการอย่างชาญฉลาด : \
FireFly

ทำจัดการเมทริกซ์ทำไมเมื่อคุณสามารถเพิ่มกฎการแปลสำหรับไม่มีการเปลี่ยนแปลงตัวละครที่ชอบ⍎'1010~∧∨⍲⍱≠=≤'['10TF~&|^vx=>'⍳⍞]? (คะแนน 33-6 = 27)
TwiNight

8

C - 165 127

นั้นน่าสนุก! ตารางการค้นหาแบบธรรมดาที่ใช้ออฟเซ็ตคงที่สำหรับการค้นหา

main(){
  char*s="100011001110110v& x = |^> /~",
       t[6]="0/xxx",
      *u= strchr((gets(t+2),t),0)-3;
  putchar(strchr(s,u[1])[*u*2+u[2]-159]);
}

ด้วยเหตุผลบางอย่างgetsไม่ได้รับการประกาศโดยปริยายดังนั้นเมื่อฉันลบสิ่งที่รวมฉันต้องเปลี่ยนgets(t+2)เป็น(gets(t+2),t)(หรือที่อื่นที่คล้ายกันเสียค่าใช้จ่ายมาก)


คำอธิบาย

ก่อนอื่นเลยเนื่องจากตารางความจริงสำหรับตัวดำเนินการมีอักขระที่ทับซ้อนกันมากมายเราจึงต้องการจัดเก็บตารางการค้นหาในแบบที่เราอนุญาตให้มีการทับซ้อน นี่คือวิธีที่ฉันเลือกเก็บพวกเขา:

v    &    x    =    |    ^    >       ~     (operation)
1000 0001 0110 1001 0111 1110 1101 01 10    (truth table [order 00,01,10,11])
0    1    3    5    7    8    9    B  D     (offset in LUT below)

0123456789ABCDE   (offsets)
100011001110110   (values)

ต่อไปเราต้องการแมปสัญลักษณ์ของโอเปอเรเตอร์กับออฟเซ็ตเหล่านี้ เราทำสิ่งนี้โดยเก็บสัญลักษณ์ตัวดำเนินการในสตริงเดียวกันที่ออฟเซ็ตคงที่จากข้อมูล LUT (กล่าวคือ 16 ตัวอักษรต่อมาคือหลังจากข้อมูล LUT โดยตรง) กระบวนการค้นหาคือ "ค้นหาตัวดำเนินการในs, ลบ16, เพิ่มleft*2+right(ซ้าย / ขวาตัวถูกดำเนินการ) สำหรับการค้นหาของการดำเนินงาน" ตัวตน "ที่ว่างเปล่าเนื่องจากวิธีการป้อนข้อมูลดึงผู้ประกอบการในกรณีนี้จะแก้ไขสิ่งที่t[1]จะเริ่มต้น - ในกรณีของเรา/ดังนั้นเราใช้/เป็นคีย์ตารางการค้นหาเพื่อแสดงการดำเนินการเอกลักษณ์เมื่อเราประมวลผลการดำเนิน~การunary " left" (สำหรับการคำนวณการค้นหาที่กล่าวถึงก่อนหน้านี้) จะเหมือนกัน/ เสมอ /เกิดขึ้นเป็นหนึ่งน้อยกว่า0ASCII ฉลาด, ความหมายเมื่อเราชดเชยตัวเลข ASCII\จะเป็นตัวแทน-1ของ เครื่องหมายสแลชในพื้นที่คีย์ของตารางการค้นหา (อักขระตัวที่สองถึงครั้งสุดท้ายในs) คือตำแหน่งเพื่อชดเชยสิ่งนี้

ถัดไปขึ้นไปการจัดการอินพุต อินพุตมีความยาวแบบไดนามิก แต่จะง่ายกว่าถ้าเรามีชื่อคงที่เฉพาะสำหรับตัวถูกดำเนินการซ้ายตัวดำเนินการและตัวถูกดำเนินการด้านขวาโดยไม่คำนึงถึงอินพุต ถ้าเราแกล้งทำเป็นว่าเราสามารถอ่านอินพุตจากขวาไปซ้ายสิ่งนี้จะเกิดขึ้นโดยอัตโนมัติ - ตัวถูกดำเนินการด้านขวามักจะเป็นตัวละครที่ถูกต้องเสมอตัวดำเนินการ (ถ้ามี) เป็นตัวเลือกที่สองจากขวาไปซ้าย ) อยู่ที่สามถึงขวาสุด เพื่อให้สามารถจัดทำดัชนีสตริงเช่นนี้เราใช้strchrเพื่อค้นหาเทอร์\0มิเนเตอร์ ( - 3เพื่อทำให้การทำดัชนีง่ายขึ้น) นี่แสดงให้เห็นว่าทำไมt[0]และt[1]กลายเป็นตัวถูกดำเนินการซ้าย / ตัวดำเนินการตามลำดับเมื่ออินพุตเป็น 1 หรือ 2 ตัว

วางกันเอาท์พุทจะเป็นputchar(strchr(s,u[1])[(u[0] - '0')*2 + (u[2] - '0') - 15])แต่บาง refactoring putchar(strchr(s,u[1])[u[0]*2+u[2]-159])และคงพับแทนที่จะได้รับเราสั้น


คุณช่วยอธิบายได้ไหมว่ามันทำงานอย่างไร
Johannes Kuhn

ตารางความจริงที่ทับซ้อนกันเป็นความคิดที่ยอดเยี่ยม คงไม่เคยคิดเรื่องนี้มาก่อนเลย :)
asteri

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

4
ฉันคิดว่าคำตอบเพิ่มเติมควรมีคำอธิบายเช่นนี้ ช่วยพวกเราที่ยังคงเรียนรู้อยู่ไม่น้อย! (และโดยผู้ที่ยังคงเรียนรู้มากหมายถึงทุกคน)
agweber

@agweber: เป็นเรื่องที่ดีที่จะได้ยินฉันค่อนข้างกังวลเกี่ยวกับคำอธิบายของฉัน และใช่ทุกคนที่นี่อาจอยู่ในช่วง "ยังคงเรียนรู้" .. อย่างน้อยฉันก็รู้ว่าฉันเป็น
FireFly

4

Tcl, 212 208-6 = 202

proc o n\ e {proc $n a\ b expr\ $e}
o > {$a<=$b}
o v {!($a|$b)}
o x {$a^$b}
o ^ {!($a&$b)}
namespace pat tcl::mathop 
lmap o\ b [lassign [split [string map {~0 1 ~1 0} $argv] {}] a] {set a [$o $a $b]}
puts $a

Ungolfed:

# Defines an operator
proc operator {name expression} {
    proc $name {a b} "expr $expression"
}
operator > {$a<=$b}
operator v {!($a|$b)}
operator x {$a^$b}
operator ^ {!($a&$b)}
# Call the commands in ::tcl::mathop if the command is not in the global namespace
namespace path tcl::mathop
# lmap instead foreach
# assume that we only got 1 argument.
foreach {op b} [lassign [string map {{~ 0} 1 {~ 1} 0} [split $argv {}]] a] {
   set a [$op $a $b]
}
puts $a

ฉันคิดว่าบรรทัด foreach ต้องการคำอธิบายบางอย่าง:

  • split $argv {} แยกสตริงอินพุต (เป็นจริงรายการ แต่โค้ดกอล์ฟ) เป็นอักขระ
  • string map {{~ 0} 1 {~ 1} 0} ...ใช้สตริงและแทนที่~ 0ด้วย1และ~ 1ด้วย0
  • lassign ... a ใช้องค์ประกอบแรกของรายการและกำหนดให้กับตัวแปร a ส่งคืนส่วนที่เหลือ
  • foreach {op b} ... {code}เดินผ่านรายการและใช้เวลา 2 องค์ประกอบในแต่ละครั้ง: opและb
  • set a [$op $a $b]ดำเนินการคำสั่งในตัวแปรopเก็บผลลัพธ์a

3

JavaScript - 107 105 ตัวอักษร

alert((x=eval(prompt().replace(/v/,'|~').replace(/\^/,'&~').replace(/x/,'^').replace(/=/,'==')))!=-1?x:0)

ฮ่าฮ่าเยี่ยมมาก นั่นเป็นประโยชน์ ไม่ได้คิดแม้แต่eval()ตอนที่ฉันทำมัน แค่ให้ฉันหน่อยเพื่อกลับบ้านและทดสอบ
asteri

1
nand = &~และ nor = |~?
Johannes Kuhn

@ โยฮันเนส: มันไม่จริง&~และ|~แต่ NAND เป็นเพียงการผกผันของและ ดังนั้นการที่บิตใดบิตหนึ่งกลับด้านก็จะกลับผลลัพธ์เช่นกัน
ProgramFOX

3

Befunge-98 - 104 101 98-6 72

... เพราะทุกภารกิจต้องการโซลูชัน esolang .. การแปลการติดตั้ง C ของฉัน แต่การประมวลผลอักขระทีละตัวแทน

#v~
2_vp5a00+*2%2\p10\%
0:<+1_v#-g5\g1
1_|#:\</2\-
.@>2%
 v   ~x^&=.>  |

สนุกจริง: การเปลี่ยนแปลง@ไปa,$และคุณได้รับแฟนซี neverending REPL แทน ( แต่ถ้าคุณทำเช่นนี้คุณจะสังเกตเห็นตัวตนที่เป็นจริง "ทำซ้ำคำสั่งสุดท้ายกับ LHS = 0 และ RHS = การป้อนข้อมูล" ซึ่งเพิ่งเกิดขึ้นที่จะเริ่มต้นกับตัวตน ) REPL ไม่มีอีกแล้ว

Ungolfed (เวอร์ชั่นก่อนหน้า):

v10001100111011v& x = |^>~
  $       1111111111222222
 1234567890123456789012345

 [read input]
> ~ :a- #v_   $ 21g " "- + 0g , @

v p11:   <
   ↑save chr

0 ←lup   [traverse LUT]
> 1+  :11g  \0g -! #v_
 v                  <
    lup chr acc
v>  :3` #v_  $"0"-\2*+

               v>   . , a,
 v       <
v> 9+9+ 21p $

แก้ไข:แรงบันดาลใจจากวิธีการแก้ปัญหาของ @jpjacobs ตอนนี้ฉันขึ้นอยู่กับตำแหน่งของตัวละครใน LUT เพื่อเป็นตัวแทนตารางความจริง เช่น|อยู่ในตำแหน่งที่ 1110 2 = 14 |เพราะตรงนี้ลงในตารางความจริงสำหรับ


มันบ้ามาก. ตกลงวิธีแก้ปัญหาทุกอย่างจะบ้าไปแล้ว
Johannes Kuhn

2

J - 65 67-6 = 61

ไม่มีข คำวิเศษณ์ ไม่นับการกำหนดฟังก์ชั่น: 67 ตัวอักษรสำหรับเวอร์ชั่น TF, 63 สำหรับเวอร์ชั่นที่ไม่ใช่ TF:

lgcTF =:".@({&('*+-+-<*01',.3 6#'.:')"1@n^:(9>n=:'&|~xv>^FT'&i.)@{.&.>&.;:)
lgc   =:".@({&('*+-+-<*',.3 4#'.:')"1@n^:(7>n=:'&|~xv>^'&i.)@{.&.>&.;:)

LgcTF จัดการทั้ง 0 และ 1 เช่นเดียวกับ T และ F

รองรับไวยากรณ์ทั้งหมดของ J ในแง่ของรถไฟวงเล็บและประเมินผลจากขวาไปซ้ายอย่างเคร่งครัด (ไม่มีกฎอื่นที่สำคัญกว่า)

อักขระทั้งหมดที่ไม่อยู่ในรายการโอเปอเรเตอร์ + Z ไม่สามารถใช้งานได้อักขระอื่น ๆ จะทำหน้าที่เหมือนกับมาตรฐาน J (รวมถึงตัวแปร)

การใช้งาน:

NB.Assign TF anyhow
T=:1 [ F=: 0
lgc 'T & F'
0
lgc ' T ~@& F' NB. negation after and = nand
NB. make a truth table
d=: 0 1
lgc 'd ~@|/ d'
1 0
0 0 
NB. and so on... 

1

Postscript 263

ความคิดของ Firefly แปลเป็น Postscript

{(0/xxx)dup 2 3 getinterval(%lineedit)(r)file exch 
readstring pop length 1 sub 3
getinterval(100011001110110v& x = |^> /~)dup
2 index 1 1 getinterval search pop exch pop exch pop 
length 3 2 roll{}forall exch pop exch 2 mul add 159 sub add 
1 getinterval =}loop

เยื้อง:

%!

{
    (0/xxx) dup 2 3 getinterval
    (%lineedit)(r)file exch % (0/xxx) file (xxx)
    readstring pop
    length % (0/xxx) len(x|xx|xxx)
    1 sub 3 getinterval % (0/x)|(/xx)|(xxx)
    (100011001110110v& x = |^> /~) dup
    2 index 1 1 getinterval search pop % (0/x)|(/xx)|(xxx) s post match pre
    exch pop exch pop % (xxx) s pre
    length 
    3 2 roll {} forall exch pop % s len(pre) u_0 u_2
    exch 2 mul add 159 sub add % s ind
    1 getinterval
    = flush
} loop

1

Befunge-93, 86 ตัวอักษร

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

~~~\:8/\5%:++00p2%\2%2*+00gg,@
0 1







1001
0001
1101
1

0
0110



1110
1000


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