using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml; using System.IO; namespace vyhodnoceni { public static class Program { private static List globalInputs = new List { }; private static List globalOutputs = new List { }; private static List gates = new List { }; private static List inputs = new List { }; private static Dictionary outputs = new Dictionary { }; public static void Main(string[] args) { string netFile = "nevnorene1"; string inputFile = "nevnorene1.in"; LoadNet(netFile); CalculateFile(inputFile); } private static void LoadNet(string netFile) { var xml = new XmlDocument(); xml.Load(netFile); // TODO catch exception foreach (XmlElement item in xml.ChildNodes[0].ChildNodes) { switch (item.Name) { case "input": globalInputs.Add(CreateOutput(item)); break; case "output": globalOutputs.Add(CreateInput(item)); break; case "gate": gates.Add(CreateGate(item)); break; default: throw new NotSupportedException("Tag " + item.Name + " neni podporovany."); } } foreach (var input in inputs) { string id = input.GetId(); if (!outputs.ContainsKey(id)) throw new Exception("Neexistuje vystupni prvek s id = '" + id + "'"); input.SetOutput(outputs[id]); } } private static void CalculateFile(string inputFile) { var reader = new StreamReader(inputFile); while (!reader.EndOfStream) { string inputLine = reader.ReadLine().Trim(); string outputLine = CalculateLine(inputLine); if (outputLine != null) { Console.WriteLine("Output: {0}", outputLine); } else { Console.WriteLine("Error"); } } Console.ReadKey(); } private static string CalculateLine(string inputLine) { if (inputLine.Length != globalInputs.Count) return null; ResetNet(); for (int i = 0; i < globalInputs.Count; i++) { globalInputs[i].SetValue(CharToBool(inputLine[i])); } bool done = false; while (!done) { bool changed = false; foreach (var gate in gates) { if (!gate.HasValue()) { changed |= gate.Calculate(); } } if (!changed) { done = true; foreach (var output in globalOutputs) { done &= output.HasValue(); if (!done) break; } if (!done) throw new Exception("Spatna sit, nejde vyresit"); } } var outputLine = new StringBuilder(globalOutputs.Count); foreach (var output in globalOutputs) { outputLine.Append(BoolToChar(output.GetValue())); } return outputLine.ToString(); } private static void ResetNet() { foreach (var item in gates) { item.Reset(); } foreach (var item in outputs) { item.Value.Reset(); } } private static char BoolToChar(bool value) { return value ? '1' : '0'; } private static bool CharToBool(char ch) { switch (ch) { case '0': return false; case '1': return true; default: throw new NotSupportedException("Znak '" + ch + "' ve vstupu neni podporovan."); } } private static Input CreateInput(XmlElement item) { string id = item.Attributes["id"].Value; var input = new Input(id); inputs.Add(input); return input; } private static Output CreateOutput(XmlElement item) { string id = item.Attributes["id"].Value; var output = new Output(id); outputs.Add(id, output); return output; } private static Gate CreateGate(XmlElement item) { string type = item.Attributes["type"].Value; type = type.ToLower(); Gate gate = null; switch (type) { case "and": gate = new AndGate(); break; case "or": gate = new OrGate(); break; case "xor": gate = new XorGate(); break; case "not": gate = new NotGate(); break; default: throw new NotSupportedException("Vnorene brany nejsou zatim podporovane."); } foreach (XmlElement child in item) { switch (child.Name) { case "input": gate.Add(CreateInput(child)); break; case "output": gate.Add(CreateOutput(child)); break; default: throw new NotSupportedException("Tag " + child.Name + " neni podporovany."); } } return gate; } } public abstract class Node { protected bool? value = null; public virtual bool HasValue() { return value != null; } public virtual bool GetValue() { return this.value.Value; } public void Reset() { value = null; } } public class ConnectionPoint : Node { protected string id; protected void init(string id) { this.id = id; } } public class Input : ConnectionPoint { protected Output output = null; public Input(string id) { init(id); } public void SetOutput(Output output) { this.output = output; } public override bool HasValue() { return this.output.HasValue(); } public override bool GetValue() { return this.output.GetValue(); } public string GetId() { return this.id; } } public class Output : ConnectionPoint { public Output(string id) { init(id); } public void SetValue(bool value) { this.value = value; } } public abstract class Gate : Node { protected List inputs = new List { }; protected List outputs = new List { }; public void Add(Input input) { inputs.Add(input); } public void Add(Output output) { outputs.Add(output); } public bool Calculate() { foreach (var input in inputs) { if (!input.HasValue()) return false; } this.value = CalculateInner(); foreach (var output in outputs) { output.SetValue(this.value.Value); } return true; } protected abstract bool CalculateInner(); } public class AndGate : Gate { protected override bool CalculateInner() { bool value = true; foreach (var input in inputs) { value &= input.GetValue(); } return value; } } public class OrGate : Gate { protected override bool CalculateInner() { bool value = false; foreach (var input in inputs) { value |= input.GetValue(); } return value; } } public class XorGate : Gate { protected override bool CalculateInner() { bool value = false; foreach (var input in inputs) { value ^= input.GetValue(); } return value; } } public class NotGate : Gate { protected override bool CalculateInner() { return !inputs[0].GetValue(); } } }