using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TruthTables
{
public class node
{
public node left;
public node right;
public node super;
public string body;
public node(node super, string body)
{
this.super = super;
this.body = body;
}
public bool isexpression()
{
return Program.kw.Contains(body);
}
}
class Program
{
public static bool evaluate(node n, bool A = false, bool B = false, bool C = false, bool D = false)
{
if (!n.isexpression())
{
bool not = n.body.Contains("!");
n.body = n.body.TrimStart('!');
bool value = n.body == "A" ? A : n.body == "B" ? B : n.body == "C" ? C : D;
if (not) { n.body = "!" + n.body; return !value; }
return value;
}
else
{
bool L = evaluate(n.left,A,B,C,D);
bool R = evaluate(n.right,A,B,C,D);
switch (n.body)
{
case "and":
return L && R;
case "or":
return L || R;
case "nor":
return !L && !R;
case "nand":
return !L || !R;
}
}
return false;
}
public static string[] kw = new string[] { "and", "or", "nor", "nand" };
public static void run()
{
Console.Write("> ");
string input = Console.ReadLine();
List<string> words = new List<string>();
int len = input.Split(' ').ToList().Count;
for (int i = 0; i < len; i++)
{
List<string> inp = input.Split(' ').ToList();
if (inp[i] == "not")
{
words.Add("!" + inp[i + 1]);
len--;
}
else
{
words.Add(inp[i]);
}
}
input = "";
words.ForEach((x) => input += x + " ");
input = input.Trim();
node root = new node(null, input);
node current;
List<node> _nodes = new List<node>();
List<node> nodes = new List<node>();
_nodes.Add(root); nodes.Add(root);
while (true)
{
current = _nodes[0];
_nodes.Remove(current);
bool done = false;
List<string> spl = new List<string>();
foreach (string w in (spl = current.body.Split(' ').ToList()))
{
if (!done)
{
if (kw.Contains(w))
{
string bodyL = ""; for (int i = 0; i < spl.IndexOf(w); i++) { bodyL += spl[i]; }
var asffa = spl.IndexOf(w);
string bodyR = ""; for (int i = spl.IndexOf(w) + 1; i < spl.Count; i++) { bodyR += spl[i] + " "; }
bodyR = bodyR.Trim(' ');
current.body = w;
current.left = new node(current, bodyL); /*nodes.Add(current.left);*/ nodes.Add(current.left);
current.right = new node(current, bodyR); _nodes.Add(current.right); nodes.Add(current.right);
done = true;
}
}
}
if (_nodes.Count <= 0) break;
}
foreach (node n in nodes)
{
if (n.body == "nor")
{
if (n.left.body.Contains('!')) n.left.body.Substring(1, n.left.body.Length - 1);
else { n.left.body = "!" + n.left.body; }
if (n.right.body.Contains('!')) n.right.body.Substring(1, n.right.body.Length - 1);
else { n.right.body = "!" + n.right.body; }
n.body = "and";
}
if (n.body == "nand")
{
if (n.left.body.Contains('!')) n.left.body.Substring(1, n.left.body.Length - 1);
else { n.left.body = "!" + n.left.body; }
if (n.right.body.Contains('!')) n.right.body.Substring(1, n.right.body.Length - 1);
else { n.right.body = "!" + n.right.body; }
n.body = "or";
}
}
List<node> nodesCopy = new List<node>();
nodes.ForEach((x) => nodesCopy.Add(x));
bool hit = false;
while (true)
{
hit = false;
foreach (node n in nodesCopy)
{
if (n.isexpression())
{
if (n.super != null)
{
if (kw.ToList().IndexOf(n.body) > kw.ToList().IndexOf(n.super.body))
{
hit = true;
node subL = n.left;
node subR = n.right;
int supIndex = nodes.IndexOf(n.super);
int subIndex = nodes.IndexOf(n);
n.left = n.super;
n.super.right = subL;
node supsuper = n.super.super;
n.super.super = n;
n.super = supsuper;
nodes[supIndex] = n;
nodes[subIndex] = n.left;
}
}
}
}
if (!hit) break;
}
root = nodes[0];
int varcount = 0;
if (input.Contains('A')) varcount++;
if (input.Contains('B')) varcount++;
if (input.Contains('C')) varcount++;
if (input.Contains('D')) varcount++;
if (varcount == 0)
{
Console.Write("No input given.");
}
else
{
for (int i = 0; i < (int)Math.Pow(2, varcount); i++)
{
string binstring = Convert.ToString(i, 2);
for (int j = binstring.Length; j < 4; j++) { binstring = "0" + binstring; }
var a = binstring.ToCharArray()[3] == '1';
var b = binstring.ToCharArray()[2] == '1';
var c = binstring.ToCharArray()[1] == '1';
var d = binstring.ToCharArray()[0] == '1';
var res = evaluate(root, a, b, c, d);
string output = "";
if (varcount > 0) output += "A: " + a + " \t";
if (varcount > 1) output += "B: " + b + " \t";
if (varcount > 2) output += "C: " + c + " \t";
if (varcount > 3) output += "D: " + d;
Console.WriteLine(output + " \t" + res);
}
}
}
static void Main(string[] args)
{
while (true)
{
run();
Console.ReadKey();
Console.Clear();
}
}
}
}