Tabelle della verità: il computer del tuo bisnonno


13

Se ti ricordi dei tuoi anni di scuola, potresti ricordare di aver appreso le Tabelle della verità . Sembravano noiosi, ma sono la base della logica e (alcuni direbbero) tutti i computer ...


Problema

La tua missione, se decidi di accettarla, è quella di scrivere un programma, una funzione o un widget di codice in grado di generare input in una tabella di verità.

Ingresso

L'input sarà una stringa (come la struttura dei dati) contenente l'istruzione logica in cui trasformare la Tabella della verità. Per esempio:

p ∧ q

Ciò significa p and q(coniugazione logica) e produrrà:

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

Notare la spaziatura: l'elemento della colonna è al centro dell'intestazione

Personaggi

Punteggio tramite caratteri, non byte I caratteri di confronto logico sono speciali e non sempre come sono. Usa questi personaggi:

Congiunzione logica (AND): U + 2227

Disgiunzione logica (OR): U + 2228

Negazione logica (NOT) ~o¬ U + 7e e U + ac rispettivamente


bonus

Tutti questi bonus sono opzionali, ma elimineranno i punti del tuo punteggio. Scegli qualsiasi.

Negazione logica

La negazione logica è un operatore unario nelle tabelle di verità. È l'equivalente di !nella maggior parte dei linguaggi basati su C. Fa false=> truee viceversa. È annotato con un ¬ o ~ (è necessario supportare entrambi). Sostenere questo eliminerà il 10% del tuo punteggio. Tuttavia, è necessario aggiungere una colonna aggiuntiva per mostrare i risultati: Ad esempio:

~p ∧ q

produrrà:

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

Bella stampa

La normale notazione da tavolo è noiosa. Rendiamolo carino! Il formato di stampa grazioso è il seguente per p ∧ qè il seguente:

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

Dettagli speciali per una stampa carina:

  • C'è un'imbottitura di 1 spazio in ogni cella
  • I valori delle celle sono ancora centrati

Se stampi piuttosto le tue tabelle, dal tuo codice e poi moltiplica per 0,6. Usa questa funzione per questo bonus:

score = 0.6 * code

Esempi

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

Regole

  • Si applicano scappatoie standard
  • Nessuna risorsa esterna
  • Se hai intenzione di infrangere le regole, sii intelligente;)

Il codice più breve (in caratteri) vince. In bocca al lupo!


4
Dalla descrizione sembrava che fossero espressioni booleane arbitrarie. Ma tutti gli esempi (senza bonus) hanno un solo operatore. È limitato a un singolo operatore? Inoltre, i nomi dei valori negli esempi sono tutti pe q. A meno che non abbiano sempre questi nomi, potresti voler mostrare alcune diverse opzioni negli esempi di test. Sono sempre una singola lettera?
Reto Koradi,

2
Poiché utilizza caratteri non ASCII, potrebbe essere utile specificare se la lunghezza del codice viene contata in caratteri o byte. Se sono byte, sarebbe utile sapere quanti byte usano i caratteri unicode.
Reto Koradi,

Semplifica :). score = 0.6 * (code - 15)=.6 * code - 9
mınxomaτ,

@RetoKoradi Changed. Punteggio per personaggi, non byte
MayorMonty

@RetoKoradi Se ciò che il mio insegnante di geometria mi dice è corretto, non vedrai mai più allora p qe rin una tabella di verità;)
MayorMonty

Risposte:


6

JavaScript (ES6), 141

Funzione semplice, nessun bonus, 141 caratteri. (140 uft8, 1 unicode largo)

Gestione complessa delle funzioni ~ o ¬, 254 caratteri (253 utf, 1 unicode largo), punteggio 229

Potrebbe salvare 6 byte usando alertinvece di console.log, ma alertè particolarmente inadatto per visualizzare le tabelle.

Prova a eseguire lo snippet di seguito in un browser compatibile con EcmaScript 6 (testato con Firefox. Non funzionerà in Chrome poiché Chrome non supporta .... Inoltre, la versione bonus utilizza un'estensione splitspecifica di 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, adoro JavaScript e questa soluzione merita un voto positivo.
Arjun,

JavaScript è la mia lingua madre, ma non lascerò che questo mi influenzi! : D Ottimo lavoro!
MayorMonty,

6

Modello MediaWiki - 2347 caratteri

MediaWiki ha una funzione modello integrata chiamata in {{#expr}}grado di gestire espressioni logiche. Questa deve essere la sfida perfetta per i modelli MediaWiki! Funzionalità come variabili, loop e una sintassi leggibile avrebbero aiutato un po ', però. Inoltre, il fatto che non ci sia un operatore NOT per la funzione expr l'ha resa un po 'più complessa.

{{#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}}

Test:

{{TemplateName|¬X ∧ ~Y}}

{{TemplateName|p ∨ q}}

Risultato:

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

Suppongo che MediaWiki> = 1.18, in cui le estensioni ParserFunctions siano fornite in bundle con il software.


2
Benvenuti in Programming Puzzle and Code Golf. L'uso di MediaWiki non è qualcosa a cui avrei pensato; +1. Tuttavia, manca il comportamento della colonna aggiuntiva dell'operatore ¬/ ~; se lo aggiungi, ti qualificherai per un 10%bonus.
wizzwizz4,

Mi sono appena reso conto che, a meno che non sia possibile utilizzare modelli nidificati (che potrebbe allungare un po 'troppo le regole?), L'aggiunta corretta di quella colonna aumenterebbe effettivamente il conteggio dei caratteri ... :)
Leo,

In tal caso, dovresti probabilmente rimuovere il supporto per la negazione, perché non ricevi alcun bonus per questo.
wizzwizz4,

Sì, lo esaminerò. Non penso che avrà un grande impatto sulla classifica finale però ...: D
Leo

1
@leo Questo è fantastico, e penso che usare modelli nidificati andrebbe bene se aggiungi semplicemente il conteggio dei personaggi di questi due, che sembra essere la pratica accettata al giorno d'oggi.
Harry

4

Python - 288 caratteri (+10 di penalità perché non sono riuscito a far funzionare l'unicode: c)

Nessun bonus. Questa è la mia prima risposta 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 è l'input.

EDIT: rimosso alcuni spazi e ora utilizza args di funzione come input.


1
Benvenuti in PP&CG! Assicurati di avere il tuo codice seguendo le regole, in base alla domanda. Come specifica della regola, il codice deve essere una funzione, un programma completo o un bit di codice. Ciò implica che l'ingresso DEVE essere STDIN o argomenti di funzione (o equivalenti) Happy Coding!
MayorMonty,

3

Dyalog APL , 58 48 caratteri

Richiede ⎕IO←0, che è predefinito su molti sistemi. Prende la stringa come argomento.

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

Nessun bonus, ma sul lato positivo, qualsiasi operatore funziona.

⍳4 primi quattro indici (0 1 2 3)

 retromarcia (3 2 1 0)

2 2⊤ tabella booleana a due bit

 diviso in un elenco di elenchi a due elementi (bit alti, bit bassi)

p q← memorizza come p e q

 conta (2) *

9⍴ rimodellare ciclicamente quello alla lunghezza 9 (2 2 2 2 2 2 2 2 2)

324⊤⍨ quindi codificare 324, ovvero come binario a 12 bit (1 0 1 0 0 0 1 0 0)

\⍨ usalo per espandere (inserisci uno spazio per ogni 0) ...

'FT '[... ] la stringa "FT", indicizzata da

⍎⍵ l'argomento eseguito (valido poiché p e q ora hanno valori)

trasformalo in una matrice di colonne

q, anteporre una colonna composta da q (1 1 0 0)

q, anteporre una colonna composta da p (1 0 1 0)

(... )⍪ inserisci una riga sopra, composta da

 l'argomento

'p q ', anteposto alla stringa "p q"


* Per favore contrassegna questo problema se vedi come ≢e non come ̸≡.


2

Julia, 161 byte

Nessun bonus.

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 byte

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

Non sono un esperto di Mathematica, ma l'ho trovato piuttosto elegante rispetto al dover fare un confronto diretto dei personaggi.

Avevo una soluzione che funzionava per negazione, ma era più lungo di quanto decollasse la riduzione del punteggio.

A seconda di ciò che si qualifica per la stampa carina, potrei provare per quel bonus. Sento che l'output in ASCII in Mathematica sarebbe troppo costoso per compensare la riduzione del punteggio, ma se le due caratteristiche principali sono un bordo tratteggiato e un'imbottitura specificata all'interno delle celle, in Grid sono solo un paio di opzioni.

Con una stampa carina, 171 * 0,6 = 102,6 byte

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 byte

Nessun bonus (con bonus alla fine)

 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])

Richiede Python3 per il supporto Unicode pronto all'uso.

Basato sul codice Python di DJgamer98, capire che il suo tavolo non è giusto.

Modifica1: suddivisione in variabili distinte e modifica della variabile stringa operatore

Edit2: (ab) usando F e T sia come variabili che come caratteri stringa

Edit3: risparmio di uno spazio grazie a NoOneIsHere

Con Bonus, 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));

Benvenuti in PPCG! È possibile salvare un byte rimuovendo lo spazio dopo q in c:.
NoOneIsHere

Edit2: Questo non è un abuso. Vedi qui , dove uso il primo carattere del contenuto del file come nome file!
Adám,

1

C / C ++ 302 byte

335 caratteri in meno del 10% per la gestione della negazione. Formattazione incompleta ma invio prima di vedere quale sia l'impatto del completamento.

Contrassegnato come C / C ++ perché il mio gcc e g ++ lo accettano con -fpermissive e mi sembra molto più simile al C ++ che al 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");}}

Sono sicuro che probabilmente ci sono alcune modifiche che potrebbero essere applicate. In effetti, gestire le nots aggiunge più del 10% di bonus rimossi.

Ciò presuppone che il formato di input sia come indicato, ovvero 2 valori di input (p e q), con o senza il prefisso not e nient'altro, e tutti i token delimitati da un singolo spazio.

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

e i test:

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 caratteri

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

è il carattere di uso privato che U+F3C7rappresenta\[Transpose] .

Fortunatamente per noi golfisti Mathematica, e già rappresentiamo Ande Or, quindi tutto ciò che dobbiamo fare è convertire la stringa di input in un'espressione Mathematica e possiamo fare operazioni logiche simboliche su di essa.

Nota che questa soluzione gestirà anche Not( ¬), Implies( ), Equivalent( ), Xor( ), Nand( ), Xor( ) e Nor( ), ma non ottiene il bonus perché~p è un errore di sintassi in Mathematica. Meh.

inserisci qui la descrizione dell'immagine

Spiegazione

b=ToExpression@#

Converte la stringa di input in un'espressione Mathematica e la memorizza in b .

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

Questa è una lista di tutte le possibili sottoespressioni dell'input. Ognuno riceverà la propria colonna.

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

Questo è un elenco di tutte le variabili che compaiono nell'input.

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

Funzione pura che accetta un'espressione di input #e restituisce un elenco di valori di verità per tutte le possibili combinazioni di valori di verità per le variabili.

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

Prepara l'espressione stessa a questo elenco.

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

Applica questa funzione a ogni sottoespressione dell'input.

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

Quindi sostituire true (0<1 ) con "T" e false ( 0>1) con "F".

(...)

Scambia righe e colonne.

Grid[...]

Visualizza il risultato come a Grid .

TraditionalForm@Grid[...]

Converti la Gridforma tradizionale in modo che utilizzi i simboli di fantasia.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.