간단한 논리 게이트 계산기


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

단항 연산자 (음수)는 항상 부울 값 앞에 나타나고 이항 연산자는 항상 두 부울 값 사이에 나타납니다. 모든 입력이 유효하다고 가정 할 수 있습니다. 문자열은 일반적인 ASCII 문자열입니다.

원하는 경우 1과 0 대신 T와 F를 사용할 수 있습니다 . 둘 다 지원하는 경우 문자 수에 -6 을 사용하십시오.

이것은 : 모든 언어에서 가장 짧은 코드가 승리합니다!


3
나는 ^상징의 이름이 캐럿 이라고 말해야 한다고 믿는다 .
FireFly

3
@FireFly Haha, 그렇습니다. 점심에 너무 가깝습니다! 감사.
asteri

답변:


6

APL (45-6 = 39)

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

지원 TF입력하지만 항상 출력 것이다 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 표현식이 될까요?
  • : 평가

주 : ~그리고 =그들은 무엇으로 대체 할 필요가 없습니다 이미 옳은 일을한다.


아주 좋아요! 이것은 APL 로의 변환 및 평가 방식입니다. J에서 gerund 기반 접근 방식을 숙고하고 있었지만 피연산자를 똑똑하게 분할하는 방법을 모르겠습니다. : \
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]는 초기화 된 모든 항목 으로 해석됩니다. 우리의 경우 -in /. 따라서, 우리가 사용하는 /식별 동작을 나타내는 룩업 테이블 키로. 우리는 단항 처리 할 때 ~동작 " left(룩업 연산 앞서 언급 용)"을 항상 동일한 것은 / . /미만을 우연히0ASCII 방식으로 ASCII 숫자 \를 보상 할 때의 의미 -1입니다. 찾아보기 테이블 키 영역의 슬래시 (마지막 문자 s, 즉 마지막 문자 )는이를 보상하기 위해 배치됩니다.

다음으로 입력 처리. 입력은 동적 길이를 갖지만 입력에 관계없이 왼쪽 피연산자, 연산자 및 오른쪽 피연산자에 대한 특정 정적 이름이 있으면 더 쉽습니다. 입력을 오른쪽에서 왼쪽으로 읽을 수 있다고 가정하면 기본적으로 자동으로 발생합니다. 오른쪽 피연산자는 항상 가장 오른쪽 문자이고 연산자 (있는 경우)는 두 번째에서 오른쪽이며 왼쪽 피연산자 (있는 경우) )는 가장 오른쪽에서 세 번째입니다. 이와 같이 문자열 을 인덱싱하기 위해 터미네이터 strchr를 찾는 데 사용 \0합니다 ( - 3인덱싱 단순화). 이것은 입력이 1 또는 2 문자 일 때 왜 t[0]그리고 t[1]왼쪽 피연산자 / 연산자가 되는지 보여줍니다 .

종합 해보면 결과는 putchar(strchr(s,u[1])[(u[0] - '0')*2 + (u[2] - '0') - 15])좋겠지 만 리팩토링과 지속적인 폴딩은 우리를 더 짧게 putchar(strchr(s,u[1])[u[0]*2+u[2]-159])만든다.


어떻게 작동하는지 설명해 주시겠습니까?
Johannes Kuhn

진리표 겹침은 훌륭한 아이디어였습니다. 저 자신을 결코 생각하지 않았을 것입니다. :)
asteri

또한 오른쪽에서 왼쪽으로 읽는 것. 가변 길이 입력 및 위치 지정이 어려울 것이라는 것을 알고 있었고, 그것을 해결하는 좋은 방법입니다. 정말 뛰어난 사고력. 개발팀에서 일하고 싶습니까? Haha
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

언 골프 드 :

# 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} ...문자열 및을 대체 소요 ~ 01~ 1와를0
  • lassign ... a 목록의 첫 번째 요소를 변수 a에 할당하고 나머지를 반환합니다.
  • foreach {op b} ... {code}목록을 통해 걸어 두 요소마다 소요 : opb
  • set a [$op $a $b]변수에서 명령을 실행하고 op결과를 저장합니다.a

3

자바 스크립트 - (107) 105 자

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

하하, 좋아 편리합니다. 내가 이것을 eval()만들 때 조차 생각조차하지 않았다 . 집에 가서 시험해 볼 시간을주세요.
asteri

1
nand = &~및 nor = |~?
Johannes Kuhn

@Johannes : 정말하지 않습니다 &~|~하지만, NAND는 단지 역이다 AND. 따라서 비트 중 하나를 뒤집 으면 결과도 반전됩니다.
ProgramFOX

3

Befunge- 98-104101 98-6 72

... 모든 작업에는 esolang 솔루션이 필요하기 때문에 C 구현을 번역하지만 한 번에 하나씩 문자를 처리합니다.

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

재미있는 사실 : 변경 @a,$당신은 당신이 할 경우에는 해당 ID가 실제로 단지의 정체성에 기본값으로 발생, "좌 = 0, 우 = 입력이 마지막 명령을 반복"되어 알 수 있습니다,하지만 (대신 멋진 네버 앤딩 REPL을 얻을 ). 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

더 이상 b. 부사. 기능 할당을 계산하지 않은 경우 : TF 버전의 경우 67 자, 비 TF 버전의 경우 63 자 :

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

LgcTF는 T와 F뿐만 아니라 0과 1을 모두 처리합니다.

기차, 괄호로 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

포스트 스크립트 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 자

y 좌표에 대한 입력의 두 번째 기호를 해시하고 (콤팩트하고 충돌을 피한 함수를 찾는 것이 약간의 작업이었습니다) 각 모듈로 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.