真相表:您曾祖父的计算机


13

如果您还记得上学的那段时间,您可能还记得有关Truth Tables的学习。它们看起来很无聊,但是它们是逻辑和(所有人都会争辩)所有计算的基础...


问题

您选择接受的任务是编写可以在给定输入的情况下输出真值表的程序,函数或代码小部件。

输入值

输入将是一个字符串(如数据结构),其中包含将真值表放入其中的逻辑语句。例如:

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   |
+---+---+-------+

漂亮印刷的特殊细节:

  • 每个单元格中有一个空格填充
  • 单元格值仍居中

如果您漂亮地打印表格,请从代码中乘以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
从描述中听起来好像这些是任意布尔表达式。但是所有示例(无奖金)都只有一个运算符。这仅限于单个操作员吗?此外,示例中值的名称为all pq。除非它们始终具有这些名称,否则您可能希望在测试示例中显示一些其他选项。他们总是一个字母吗?
Reto Koradi

2
由于此命令使用非ASCII字符,因此最好指定代码的长度是以字符还是字节为单位。如果是字节,那么知道Unicode字符使用多少个字节会很有帮助。
Reto Koradi

简化:)。score = 0.6 * (code - 15)=.6 * code - 9
mınxomaτ

@RetoKoradi已更改。按字符而不是字节评分
MayorMonty 2015年

@RetoKoradi如果我的老师几何告诉我是正确的,你永远不会看到更多的则p qr在真值表;)
MayorMonty

Answers:


6

JavaScript(ES6),141

功能简单,无奖金,141个字符。(140 uft8,1个unicode宽)

复杂函数处理〜或¬,254个字符(253个utf,1个unicode宽),得分229

可以使用alert代替节省6个字节console.log,但是alert特别不适用于显示表。

请在符合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,因此该解决方案值得赞扬。
Arjun

JavaScript是我的母语,但是我不会让它影响我!:D干得好!
MayorMonty 2015年

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
欢迎使用编程难题和Code Golf。我不会想到使用MediaWiki。+1。但是,缺少¬/ ~运算符的额外列行为;如果添加,您将有资格获得10%奖金。
wizzwizz4 2016年

我只是意识到,除非可以使用嵌套模板(可能会使规则扩展得太远?),否则正确添加该列实际上会增加字符数... :)
leo

在这种情况下,您可能应该删除否定支持,因为您没有获得任何好处。
wizzwizz4 2016年

是的,会调查一下。我认为这不会对最终排名产生太大影响...:D
狮子座

1
@leo太好了,我认为如果只添加两个模板的字符数,使用嵌套模板就可以了,这似乎是当今公认的做法。
哈里

4

Python-288个字符(+10罚款导致我无法使unicode正常工作: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 是输入。

编辑:删除了几个空格,它现在使用函数args作为输入。


1
欢迎来到PP&CG!根据问题,请确保您的代码遵循规则。作为规则规范,您的代码必须是函数,完整程序或部分代码。这意味着输入必须是STDIN或函数参数(或等效参数)快乐编码!
MayorMonty

3

Dyalog APL58 48个字符

要求⎕IO←0,这在许多系统上都是默认设置。将字符串作为参数。

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

没有奖金,但从正面来看,任何运营商都可以工作。

⍳4 前四个索引(0 1 2 3)

 反向(3 2 1 0)

2 2⊤ 两位布尔表

 分为两个元素的列表列表(高位,低位)

p q← 存储为pq

 提示他们(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输出对于补偿分数降低而言太昂贵了,但是如果两个主要功能是虚线边框和单元格内指定的填充,那在Grid中只是几个选择。

打印精美时,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代码,弄清楚他的表是不正确的。

编辑1:拆分为不同的变量,并省略运算符字符串变量

编辑2:(ab)使用F和T作为变量和字符串字符

Edit3:通过NoOneIsHere节省一个空间

有奖金,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

Edit2:那不是滥用。见这里,这里我使用的文件内容的第一个字符作为文件名!
2013年

1

C / C ++ 302字节

335个字符减去10%的否定值。格式化不完整,但在我看到完成的影响之前先提交。

之所以被标记为C / C ++,是因为我的gcc和g ++用-fpermissive接受了它,并且对我而言,它看起来比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),带或不带not前缀,无其他,所有令牌由单个空格分隔。

取消高尔夫:

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高尔夫球手,并且 已经代表AndOr,因此我们要做的就是将输入字符串转换为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为传统形式,以便使用花式符号。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.