シンプルな論理ゲート計算機


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

単項演算子(否定)は常にブール値の前に表示されますが、2項演算子は常に2つのブール値の間に表示されます。すべての入力が有効であると想定できます。文字列は通常のASCII文字列です。

必要に応じて、1と0ではなくTとFを使用できます。両方をサポートしている場合は、-6を文字数として使用できます 。

これはです:どの言語でも最短のコードが勝ちます!


3
^シンボル名にはキャレット書いておくべきだと思います
FireFly 2013年

3
@FireFlyハハ、あなたは正しい。ランチに近すぎます!ありがとう。
アステリ2013年

回答:


6

APL(45-6 = 39)

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

TおよびFを入力としてサポートしますが、常に出力0またはになり1ます。

説明:

  • Z←⍞:行を読み取って保存します Z
  • L←'TF&|^vx>'⍳Z:内'TF&|^vx>'の各文字のインデックスを取得し、その文字が内にない場合Zに与えます。9'TF&|^vx>'
  • '10∧∨⍲⍱≠≤*'[... ]:で対応する文字を検索し'10∧∨⍲⍱≠≤*'ます。(したがって、最初のリストになかった文字はになります*)。
  • ↓⍉Z⍪⍉⍪:これを行列にして、元の(Z)をその上に置き、文字列のリストに分割します。最初の文字が元で、2番目の文字がその翻訳(ある場合)です。
  • (1+9≠L)⌷¨:これらの文字列のそれぞれについて、翻訳がなかった場合L=9(その場所にある場合)の最初の文字と、翻訳された場合は2番目の文字を取得します。
  • 例:入力があったならばT|0、我々は持っているだろう1∨0、対応するAPLの表現である今では
  • :評価

注:~=彼らは何で交換する必要はありませんので、正しいことをすでに行います。


非常に素晴らしい!これは、APLに変換して評価するアプローチですよね?私はJでのgerundベースのアプローチを考えていましたが、オペランドをうまく分割する方法がわかりません。:\
FireFly 2013年

のように変更なしの文字の変換ルールを単に追加できるのに、なぜマトリックス操作を行うの⍎'1010~∧∨⍲⍱≠=≤'['10TF~&|^vx=>'⍳⍞]ですか?(スコア33-6 = 27)
TwiNight 2013年

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」(ルックアップ計算のために先に述べた)は常に同じである//1未満であることを起こります0ASCIIワイズ、我々はASCII数字を補う際に意味を\表します-1。ルックアップテーブルのキー領域のスラッシュ(の最後から2番目の文字s)は、これを補正するために配置されます。

次に、入力処理。入力は動的な長さですが、入力に関係なく、左のオペランド、演算子、および右のオペランドに特定の静的名があると、より簡単になります。入力を右から左に読み取れるふりをすると、これは基本的に自動的に行われます。右のオペランドは常に右端の文字であり、演算子(存在する場合)は右から2番目、左のオペランド(存在する場合)です。 )は右から3番目です。このように文字列にインデックスを付けることができるよう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

真理値表のオーバーラップは素晴らしいアイデアでした。私自身はそのことを考えたことがないでしょう。:)
アステリ2013年

また、右から左に読む。可変長の入力と配置が難しいことを知っていましたが、それはそれを解決する優れた方法です。すぐに使える優れた考え方。開発チームで働きたいですか?ハハ
アステリ

4
もっと多くの答えがこのような説明を持つべきだと思います。まだかなりのことを学んでいる私たちを助けます!(そして、まだかなりのことを学んでいる人は、全員を意味します)
agweber 2013年

@agweber:聞いてよかった。説明について少し心配だった。そして、はい、おそらくここにいる全員が「まだ学習中」の段階にあります。まあ、少なくとも私はそうです。
FireFly 2013年

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}リストの上に歩くと、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()私がこれをいつ作ったか考えさえしませんでした。家に帰ってテストしてみてください。
アステリ2013年

1
nand = &~およびnor = |~
Johannes Kuhn

@ヨハネス:実際には&~and |~ではありませんが、NANDはANDの逆です。したがって、ビットの1つを反転すると、結果も反転します。
ProgramFOX 2013年

3

Befunge- 98-104 101 98-6 72

...すべてのタスクがesolangソリューションを必要とするためです。私のC実装の変換ですが、代わりに一度に1つずつ文字を処理します。

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

楽しい事実:を変更する@a,$、代わりにファンシーな無限のREPLが得られます(ただし、これを行うと、IDが実際には「lhs = 0とrhs = inputを使用して最後のコマンドを繰り返す」ことに気づくでしょう。 )。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にあります|。これはの真理値表に対応するためです。


それはクレイジーです。わかりました、befungeのすべてのソリューションはクレイジーです。
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文字

入力の2番目のシンボルをハッシュし(コンパクトで衝突を回避する関数を見つけることは、いくらかの作業でした)、y座標で、最初と3番目のシンボルをそれぞれ2を法とするx座標の2つの最下位ビットとして、指定された位置にある値を取得します。真理値表を格納/アドレス指定するためのより優れたハッシュ関数またはよりコンパクトな方法は、長さを削減できる2つの可能な方法にすぎません。

~~~\: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.