真理値表:great祖父のコンピューター


13

学校時代に戻ったことを思い出すと、真理値表について学んだことを覚えているかもしれません。彼らは退屈そうに見えたが、彼らは論理の基盤であり、(一部の人は主張する)すべてのコンピューティング...


問題

あなたの使命は、あなたがそれを受け入れることを選択した場合、入力が与えられた真理値表を出力できるコードのプログラム、関数、またはウィジェットを書くことです。

入力

入力は、真理値表を作成する論理ステートメントを含む文字列(データ構造など)になります。例えば:

p ∧ q

これはp and q(論理結合)を意味し、以下を出力します:

 p  q  p ∧ q
 T  T    T
 T  F    F
 F  T    F
 F  F    F            

間隔に注意してください:列のアイテムはヘッダーの中央にあります

キャラクター

バイトではなく文字でスコアを付ける 論理比較文字は特別であり、常に見た目が同じではありません。次の文字を使用します。

論理積(AND):U + 2227

論理和(OR):U + 2228

論理否定(NOT)~またはそれぞれ¬U + 7eおよびU + ac


ボーナス

これらのボーナスはすべてオプションですが、スコアからポイントを奪います。どれか選んでください。

論理否定

論理否定は、真理値表の単項演算子です。!ほとんどのCベースの言語と同等です。それは可能false=> trueと万力その逆。¬ またはで 表記され~ます(両方をサポートする必要があります)。これをサポートすると、スコアの10%がノックオフされます。ただし、結果を表示するには追加の列を追加する必要があります。例:

~p ∧ q

出力されます:

p  ~p  q  ~p ∧ q
T  F   T     F
T  F   F     F
F  T   T     T
F  T   F     F

プリティプリント

通常のテーブル表記は退屈です。きれいにしましょう!プリティプリントの形式は次のとおりですp ∧ q

+---+---+-------+
| p | q | p ∧ q |
+---+---+-------+
| T | T |   T   |
+---+---+-------+
| T | F |   F   |
+---+---+-------+
| F | T |   F   |
+---+---+-------+
| F | F |   F   |
+---+---+-------+

プリティ印刷の特別な詳細:

  • 各セルに1つのスペースパディングがあります
  • セル値はまだ中央揃えです

コードからテーブルをきれいに印刷し、0.6を掛けます。このボーナスにこの機能を使用します。

score = 0.6 * code

p ∧ q

p  q  p ∧ q
T  T    T
T  F    F
F  T    F
F  F    F

p ∨ q

p  q  p ∨ q
T  T    T
T  F    T
F  T    T
F  F    F

~p ∧ q

p  ~p  q  ~p ∧ q
T   F  T     F
T   F  F     F
F   T  T     T
F   T  F     F

~p ∨ q

p  ~p  q  ~p ∧ q
T   F  T     T
T   F  F     F
F   T  T     T
F   T  F     T

ルール

  • 標準的な抜け穴が適用されます
  • 外部リソースなし
  • あなたが規則を破ろうとするなら、賢くてください;)

最短コード(文字数)が優先されます。幸運を!


4
説明から、これらは任意のブール式であるように思えた。ただし、すべての例(ボーナスなし)には演算子が1つしかありません。これは単一のオペレーターに制限されていますか?また、例の値の名前はall pおよびqです。それらに常にこれらの名前がある場合を除き、テスト例でいくつかの異なるオプションを表示することができます。それらは常に単一の文字ですか?
レトコラディ

2
これは非ASCII文字を使用するため、コードの長さを文字数またはバイト数のどちらでカウントするかを指定するとよい場合があります。バイトの場合、Unicode文字が使用するバイト数を知っておくと役立ちます。
レトコラディ

簡素化する :)。score = 0.6 * (code - 15)=.6 * code - 9
mınxomaτ

@RetoKoradiが変更されました。バイトではなく文字でスコア
-MayorMonty

私の幾何学の先生が私に語っ何@RetoKoradiもしあなたがもっとして見ることはありません正しいp qr真理値表に;)
MayorMonty

回答:


6

JavaScript(ES6)、141

シンプルな機能、ボーナスなし、141文字。(140 uft8、1ユニコード幅)

複雑な関数処理〜または¬、254文字(253 utf、1ユニコード幅)、スコア229

alert代わりにを使用して6バイト節約できますがconsole.logalertテーブルの表示には特に適していません。

EcmaScript 6準拠のブラウザーで以下のスニペットを実行してテストします(Firefoxでテスト済み。Chromeはサポートしていないため、Chromeでは動作しません...。また、ボーナスバージョンsplitはFirefox固有の拡張機能を使用します)。

/* TEST: redirect console.log into the snippet body */ console.log=x=>O.innerHTML+=x+'\n'

// Simple
F=s=>{[a,o,b]=[...s],z='  ',r=a+z+b+z+a+` ${o} ${b}
`;for(w='FT',n=4;n--;r+=w[c]+z+w[e]+z+z+w[o<'∧'?c|e:c&e]+`
`)c=n&1,e=n>>1;console.log(r)}

// Simple, more readable
f=s=>{
   [a,o,b]=[...s]
   r=a+'  '+b+'  '+a+` ${o} ${b}\n`
   for(w='FT',n=4; n--; )
   {
     c = n&1, e = n>>1, x=o<'∧' ? c|e : c&e
     r += w[c]+'  '+w[e]+'    '+w[x]+'\n'
   }
   console.log(r)
}

// 10% Bonus
B=s=>{[a,o,b]=s.split(/([∧∨])/),t=a>'z',u=b>'z',z='  ',r=(t?a[1]+z:'')+a+z+(u?b[1]+z:'')+b+z+a+` ${o} ${b}
`;for(s=v=>'FT'[v]+z,n=4;n--;r+=s(c)+(t?s(d)+' ':'')+s(e)+(u?s(f)+' ':'')+(t?'   ':z)+s(o<'∧'?d|f:d&f)+`
`)c=n&1,d=c^t,e=n>>1,f=e^u;console.log(r)}

Test1 = ['q∨p','q∧p']
Test2 = Test1.concat([
  '~q∨p','q∨~p','~q∨~p','~q∧p','q∧~p','~q∧~p',
  '¬q∨p','q∨¬p','¬q∨¬p','¬q∧p','q∧¬p','¬q∧¬p'
])


console.log('SIMPLE')
Test1.forEach(t=>F(t));

console.log('BONUS')
Test2.forEach(t=>B(t));
<pre id=O></pre>


1
+1、私はJavaScriptが大好きで、このソリューションは賛成に値します。
アルジュン

JavaScriptは私の母国語ですが、それが私に影響を与えないようにします!:Dいい仕事だ!
MayorMonty

6

MediaWikiテンプレート-2347文字

MediaWikiには、{{#expr}}論理式を処理できるという組み込みのテンプレート関数があります。これはMediaWikiテンプレートにとって完璧な挑戦でなければなりません!ただし、変数、ループ、読み取り可能な構文などの機能は少し役立ちました。また、expr関数にはNOT演算子がないため、少し複雑になりました。

{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}} {{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}} {{{1}}}<br>T T &nbsp;{{#if:{{#pos:{{#sub:{{#replace:{{{1}}}|~|¬}}|0|1}}|¬}}|&nbsp;|}} {{#replace:{{#replace:{{#expr:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{{1}}}|~|¬}}|{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}}}|0|1}}}}|{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}}}|0|1}}|0|1}}|¬|}}|∧|and}}|∨|or}}}}|1|T}}|0|F}}<br>T F &nbsp;{{#if:{{#pos:{{#sub:{{#replace:{{{1}}}|~|¬}}|0|1}}|¬}}|&nbsp;|}} {{#replace:{{#replace:{{#expr:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{{1}}}|~|¬}}|{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}}}|0|1}}}}|{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}}}|1|0}}|1|0}}|¬|}}|∧|and}}|∨|or}}}}|1|T}}|0|F}}<br>F T &nbsp;{{#if:{{#pos:{{#sub:{{#replace:{{{1}}}|~|¬}}|0|1}}|¬}}|&nbsp;|}} {{#replace:{{#replace:{{#expr:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{{1}}}|~|¬}}|{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}}}|1|0}}}}|{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}}}|0|1}}|0|1}}|¬|}}|∧|and}}|∨|or}}}}|1|T}}|0|F}}<br>F F &nbsp;{{#if:{{#pos:{{#sub:{{#replace:{{{1}}}|~|¬}}|0|1}}|¬}}|&nbsp;|}} {{#replace:{{#replace:{{#expr:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{#replace:{{{1}}}|~|¬}}|{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{#replace:{{#replace:{{{1}}}|~|}}|¬|}}|0|1}}}}|1|0}}}}|{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}|{{#if:{{#pos:{{#replace:{{{1}}}|~|¬}}|¬{{#sub:{{{1}}}|{{#expr:{{#len:{{{1}}}}}-1}}|{{#len:{{{1}}}}}}}}}|1|0}}|1|0}}|¬|}}|∧|and}}|∨|or}}}}|1|T}}|0|F}}

テスト:

{{TemplateName|¬X ∧ ~Y}}

{{TemplateName|p ∨ q}}

結果:

X Y ¬X ∧ ~Y
T T    F
T F    F
F T    F
F F    T

p q p ∨ q
T T   T
T F   T
F T   T
F F   F

MediaWiki> = 1.18を想定しています。ここでは、ParserFunctions拡張機能がソフトウェアにバンドルされています。


2
プログラミングパズルとコードゴルフへようこそ。MediaWikiの使用は、私が考えていたものではありません。+1。ただし、¬/ ~演算子の余分な列の動作はありません。追加すると、10%ボーナスの資格が得られます。
wizzwizz4

ネストされたテンプレートを使用できない限り(ルールを少し拡張しすぎているかもしれません)、その列を適切に追加すると実際に文字数が増えることに気付きました... :)
leo

どちらの場合も、否定のサポートを削除する必要があります。これは、ボーナスを受け取っていないためです。
wizzwizz4

はい、調べます。しかし、最終的なランキングに大きな影響を与えるとは思わない...:D
leo

1
@leoこれは素晴らしいことです。ネストされたテンプレートの使用は、それらの2つの文字数を追加するだけでうまくいくと思います。これは最近受け入れられている慣行のようです。
ハリー

4

Python-288文字(+10ペナルティにより、ユニコードが機能しませんでした:c)

ボーナスなし。これは私の最初のコードゴルフの答えです。

def f(i):
    i=i.split(" ")
    print i[0],i[2],
    for f in i[0:3]: print f,
    print ""
    for t in["TT","TF","FT","FF"]:
        p,q=t[0],t[1]
        y = t[0]+" "+t[1]
        if i[1]=="^": r=(False,True)[p==q]
        if i[1]=="v": r=(False,True)[p!=q]
        if r: y+="   T"
        else: y+="   F"
        print y

i 入力です。

編集:いくつかのスペースを削除し、関数の引数を入力として使用するようになりました。


1
PP&CGへようこそ!質問に従って、ルールに従っていることを確認してください。ルールの仕様として、コードは関数、完全なプログラム、またはコードの一部でなければなりません。これは、入力がSTDINまたは関数引数(または同等のもの)でなければならないことを意味しますHappy Coding!
MayorMonty

3

Dyalog APL58 48文字

が必要⎕IO←0です。これは多くのシステムでデフォルトです。引数として文字列を取ります。

{('p q ',⍵)⍪'FT '[p,q,⍪⍎⍵]\⍨324⊤⍨9⍴≢p q←↓2 2⊤⌽⍳4}

ボーナスはありませんが、プラス側では、どのオペレーターでも機能します。

⍳4 最初の4つのインデックス(0 1 2 3)

 リバース(3 2 1 0)

2 2⊤ 2ビットのブール表

 リストの2要素リストに分割(高ビット、低ビット)

p q←pおよびq  として保存

 それらを集計します(2)*

9⍴ これを長さ9(2 2 2 2 2 2 2 2 2 2)に周期的に再形成する

324⊤⍨ したがって、324をエンコードします。つまり、12ビットバイナリ(1 0 1 0 0 0 1 0 0)として

\⍨ それを使用して展開します(0ごとにスペースを挿入します)...

'FT '[... ] 文字列「FT」、インデックス付き

⍎⍵ 実行された引数(pqが値を持つようになったため有効)

それを列行列にする

q,q(1 1 0 0)で 構成される列を追加します

q,p(1 0 1 0)で 構成される列を追加します

(... )⍪ 上に行を挿入します。

 引数

'p q ', 文字列「p q」を先頭に追加


* としてではなくと表示されている場合は、この問題にスターを付けください。≢̸≡


2

ジュリア、161バイト

ボーナスなし。

s->(S=split(s);P=println;p=S[1];q=S[3];a=[&,|][(S[2]=="∨")+1];c="  ";P(p,c,q,c,s);for t=["TT","TF","FT","FF"] P(t[1],c,t[2],c^2,"FT"[a(t[1]>'F',t[2]>'F')+1])end)

ゴルフをしていない:

function f(s::String)
    # Split the input on spaces
    S = split(s)

    # Separate out the pieces of the statement
    p = S[1]
    q = S[3]
    a = [&, |][(S[2] == "∨") + 1]

    # Print the header
    println(p, "  ", q, "  ", s)

    # Create the table entries in a loop
    for t = ["TT", "TF", "FT", "FF"]
        println(t[1], "  ", t[2], "    ", "FT"[a(t[1] > 'F', t[2] > 'F') + 1])
    end
end

1

Mathematica、129バイト

ゴルフ済み:

t=InputString[];s=Append[StringCases[t,LetterCharacter],t];Grid[Prepend[Map[If[#,"T","F"]&,BooleanTable[ToExpression[s]],{2}],s]]

ゴルフをしていない:

(*Take input*)
t=InputString[];
(* Find all occurrences of letters and append the final statement.*)
s=Append[StringCases[t,LetterCharacter],t];
(* Evaluate the list as expressions and create a boolean table of True/False values, then display as a table. *)
(* To satisfy the output conditions, we must convert each True/False to T/F *)
Grid[Prepend[Map[If[#,"T","F"]&,BooleanTable[ToExpression[s]],{2}],s]]

Mathematicaの専門家ではありませんが、直接文字を比較する必要があるのに比べて、これはかなりエレガントであることがわかりました。

私は否定のために働いた解決策を持っていましたが、それはスコアの減少が始まるよりも長かったです。

プリティ印刷の対象に応じて、そのボーナスを試すことができます。MathematicaでASCIIで出力することは、スコアの減少を補うにはあまりにも高価すぎると思いますが、2つの主要な機能が点線の境界とセル内の指定されたパディングである場合、それはグリッドのいくつかのオプションです。

プリティ印刷では、171 * 0.6 = 102.6バイト

t=InputString[];s=Append[StringCases[t,LetterCharacter],t];Grid[Prepend[Map[If[#,"T","F"]&,BooleanTable[ToExpression[s]],{2}],s],Spacings->1,Frame->All,FrameStyle->Dashed]

1

Python3、 145 139 120 119のバイト

ボーナスなし(最後にボーナスあり)

 def f(s):
 a,m,b=s.split(" ");print(a,b,s);F,T,c=0,1,"FT"
 for p in c:
  for q in c:print(p,q," ",c[eval(p+"+*"[m=="∧"]+q)>0])

すぐに使えるUnicodeサポートのためのPython3が必要です。

DJgamer98 Pythonコードに基づいて、彼のテーブルを理解することは正しくありません。

Edit1:個別の変数に分割し、演算子文字列変数を省略します

Edit2:(ab)FとTを変数と文字列文字の両方として使用

編集3:NoOneIsHereのおかげで1つのスペースを節約

ボーナスあり、215 * 0.6 = 129

def f(s):
 r="+---"*3+"----+"
 a,m,b=s.split(" ");F,T,c=0,1,"FT"
 print("%s\n| %s | %s | %s |\n%s"%(r,a,b,s,r));
 for p in c:
  for q in c: print("| %s | %s |   %s   |\n%s"%(p,q,c[eval(p+"+*"[m=="∧"]+q)>0],r));

PPCGへようこそ!後にスペースを削除することでバイトを節約できますq in c:
-NoOneIsHere

編集2:それは虐待ではありません。ファイルの内容の最初の文字をファイル名として使用するここを参照してください!
アダム

1

C / C ++ 302バイト

否定を処理するための335文字から10%減。フォーマットは不完全ですが、完了の影響がわかる前に送信しています。

私のgccとg ++が-fpermissiveでそれを受け入れ、C ++よりもはるかにCのように見えるため、C / C ++としてマークされています。

#include <stdio.h>
void T(char*S) { int (*P)(char*,...)=printf;char*v[2]={"F","T"};for(int m=4;m--;){P("|");char*s=S;int x=m&1;X:P(" %s |",v[x]);if(*++s!=' '){x=x^1;goto X;}char*o=++s;s+=3;int y=(m>>1)&1;Y:P(" %s |",v[y]);if(*++s){y=y^1;goto Y;}int g;for(g=o-S+1;g--;)P(" ");P(*++o==39?v[x&y]:v[x|y]);for(g=s-o;g--;)P(" ");P("|\n");}}

おそらくいくつかの調整が適用される可能性があると確信しています。実際、notsを処理すると、10%のボーナス削除よりも多くが追加されます。

これは、入力形式が前述のとおりである、つまり、2つの入力値(pおよびq)で、接頭辞なしと他の何もない場合、および単一スペースで区切られたすべてのトークンがあることを前提としています。

ゴルフをしていない:

void ungolfed(char* S)
{
   int (*P)(char*,...) = printf;         // useful lookup stuff
   char* v[2] = {"F","T"};

   for(int m = 4; m--;) {                // loop over all 2 bit bit patterns (truth table inputs)

      P("|");                            // start of line format
      char* s=S;                         // iterator to start of equation for each bit pattern

      int x = m&1;                       // input 1 (aka. p which I called x here to be awkward)
X:    P(" %s |",v[x]);                   // input 1 output and format

      if(*++s!=' ') {                    // if next character is not a space then input must be prefixed with the not character
         x=x^1;                          // so negate the input
         goto X;                         // and redo input 1 output
      }

      char* o = ++s;                     // remember where the operator is
      s+=3;                              // and skip it and following space

      int y = (m>>1)&1;                  // input 2 (aka. q which I called y obviously) processing as for input 1
Y:    P(" %s |",v[y]);

      if(*++s) {
         y=y^1;
         goto Y;
      }

      int g;

      for(g=o-S+1;g--;) P(" ");         // pre-result value padding

      P(*++o==39?v[x&y]:v[x|y]);      // result

      for(g=s-o;g--;) P(" ");           // post-result value padding and format
      P("|\n");
   }
}

およびテスト:

int main()
{
   T("p \x22\x27 q");  // p & q
   puts("");

   T("p \x22\x28 q");  // p | q
   puts("");

   T("\x7ep \x22\x27 q");  // ~p & q
   puts("");

   T("\xacp \x22\x28 q");  // ~p | q
   puts("");

   T("p \x22\x28 \xacq");  // p | ~q
   puts("");

   return 0;
}

0

Mathematica、128文字

TraditionalForm@Grid[({#}~Join~BooleanTable[#,Cases[b,_Symbol,{0,∞}]]&/@Cases[b=ToExpression@#,_,{0,∞}]/.{0<1->"T",0>1->"F"})]&

U+F3C7表す私的使用の文字です\[Transpose]です。

幸いなことにMathematicaゴルファーは すでにとを表現AndしているOrので、入力文字列をMathematica式に変換するだけで、その上で記号論理演算を行うことができます。

このソリューションもNot¬)、Implies)、Equivalent)、Xor)、Nand)、Xor)、Nor)を処理~pしますが、Mathematicaの構文エラーであるため、ボーナスは得られません。えー

ここに画像の説明を入力してください

説明

b=ToExpression@#

入力文字列をMathematica式に変換し、に保存しbます。

Cases[b=ToExpression@#,_,{0,∞}]

これは、入力の可能なすべての部分式のリストです。それぞれが独自の列を受け取ります。

Cases[b,_Symbol,{0,∞}]

これは、入力に表示されるすべての変数のリストです。

BooleanTable[#,Cases[b,_Symbol,{0,∞}]]&

入力式を受け取り#、変数の真理値のすべての可能な組み合わせの真理値のリストを返す純粋な関数。

{#}~Join~BooleanTable[...]

式自体をこのリストの先頭に追加します。

.../@Cases[b=ToExpression@#,_,{0,∞}]

この関数を入力の各部分式に適用します。

.../.{0<1->"T",0>1->"F"}

次に、true(0<1)を「T」に、false(0>1)を「F」に置き換えます。

(...)

行と列を交換します。

Grid[...]

結果をとして表示しGridます。

TraditionalForm@Grid[...]

Gridファンシーシンボルを使用するように従来の形式に変換します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.