Таблицы правды: компьютер вашего прадеда


13

Если вы вспоминаете свои школьные годы, вы, возможно, помните, что изучали Таблицы правды . Они казались скучными, но они являются основой для логики и (некоторые могут поспорить) всех вычислений ...


проблема

Ваша миссия, если вы решите принять ее, это написать программу, функцию или виджет кода, который может выводить таблицу истинности при заданном входном сигнале.

вход

Входными данными будет строка (например, структура данных), содержащая логический оператор, в который будет преобразована таблица истинности. Например:

p ∧ q

Это значит p and q(логическая конъюнкция) и выдаст:

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

Обратите внимание на интервал: элемент столбца находится в центре заголовка

Персонажи

Оценка через символы, а не байты . Символы логического сравнения особенные и не всегда выглядят так, как они выглядят. Используйте эти символы:

Логическое соединение (И): U + 2227

Логическая дизъюнкция (ИЛИ): U + 2228

Логическое отрицание (НЕ) ~или ¬U + 7e и ​​U + ac соответственно


Бонусы

Все эти бонусы не являются обязательными, но будут сбивать очки с вашего счета. Выберите любой.

Логическое Отрицание

Логическое отрицание - это унарный оператор в таблицах истинности. Это эквивалент !большинства языков на основе Си. Это делает 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
Из описания это звучало так, как будто это были произвольные булевы выражения. Но все примеры (без бонусов) имеют только одного оператора. Это ограничено одним оператором? Также в именах значений в примерах есть все pи q. Если у них не всегда есть эти имена, вы можете захотеть показать несколько разных вариантов в тестовых примерах. Это всегда одна буква?
Рето Коради

2
Поскольку при этом используются не-ASCII-символы, было бы целесообразно указать, считается ли длина кода в символах или байтах. Если это байты, было бы полезно узнать, сколько байтов используют символы Юникода.
Рето Коради,

Упростить :). score = 0.6 * (code - 15)=.6 * code - 9
mynxomaτ

@RetoKoradi Изменено. Оценка по символам, а не по байтам
MayorMonty

@RetoKoradi Если то, что говорит мне мой учитель геометрии, правильно, вы никогда не увидите больше p qи rв таблице истин;)
MayorMonty

Ответы:


6

JavaScript (ES6), 141

Простая функция, без бонусов, 141 символов. (140 футов8, ширина 1 юникод)

Сложная функция обработки ~ или, 254 символа (253 UTF, 1 Unicode в ширину), оценка 229

Может сэкономить 6 байт, используя alertвместо 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, и это решение заслуживает одобрения.
Арджун

JavaScript - мой родной язык, но я не позволю этому повлиять на меня! : D Хорошая работа!
Мэр Монти

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

Я только что понял, что, если я не могу использовать вложенные шаблоны (что может слишком сильно растягивать правила?), Правильное добавление этого столбца фактически увеличит количество символов ... :)
Лев

В этом случае вам, вероятно, следует удалить поддержку отрицания, потому что вы не получаете за это никаких бонусов.
wizzwizz4

Да, будет смотреть на это. Я не думаю, что это окажет большое влияние на окончательный рейтинг ...: D
Лев

1
@leo Это здорово, и я думаю, что использование вложенных шаблонов было бы хорошо, если бы вы просто добавили счетчик символов для двух из них, что, похоже, является общепринятой практикой в ​​настоящее время.
Гарри

4

Python - 288 символов (+10 штрафов, потому что я не могу заставить работать юникод: c)

Нет бонусов. Это мой самый первый ответ Codegolf.

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 APL , 58 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← хранить как p и q

 подсчитать их (2) *

9⍴ циклически изменить это до длины 9 (2 2 2 2 2 2 2 2 2)

324⊤⍨ кодировать 324 таким образом, то есть как 12-битный двоичный код (1 0 1 0 0 0 1 0 0)

\⍨ используйте это для расширения (вставьте пробел для каждого 0) ...

'FT '[... ] строка "FT", проиндексированная

⍎⍵ выполненный аргумент (действителен, поскольку p и q теперь имеют значения)

превратить это в матрицу столбцов

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)

Ungolfed:

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 байт

Golfed:

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

Ungolfed:

(*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, но я нашел это довольно элегантным по сравнению с необходимостью прямого сравнения символов.

У меня было решение, которое работало на отрицание, но это было дольше, чем снимет оценка.

В зависимости от того, что подходит для красивой печати, я мог бы попытаться получить этот бонус. Я чувствую, что вывод в ASCII в Mathematica будет слишком дорогим, чтобы компенсировать снижение оценки, но если две основные функции - это пунктирная граница и заданный отступ внутри ячеек, это только пара вариантов в 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])

Необходимая поддержка Python3 для Unicode из коробки.

Исходя из кода Python DJgamer98, выяснить его таблицу не правильно.

Edit1: разделение на отдельные переменные и пропуск операторной строковой переменной

Edit2: (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: это не злоупотребление. Смотрите здесь , где я использую первый символ содержимого файла в качестве имени файла!
Адам

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");}}

Я уверен, что, возможно, есть несколько настроек, которые можно применить. На самом деле, обработка неимущих добавляет более 10% бонуса.

Предполагается, что входной формат соответствует указанному, то есть 2 входных значения (p и q), с префиксом not и без него и без него, со всеми токенами, разделенными одним пробелом.

Ungolfed:

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традиционную форму, чтобы использовать необычные символы.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.