static List <Gate> ReadInput() { List <Gate> list = new List <Gate>(); string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), @"..\..\..\input.txt"); StreamReader reader = File.OpenText(path); Regex regexSetPass = new Regex(@"^(\d+|[a-z]+) -> ([a-z]+)"); Regex regexAndOr = new Regex(@"(\d+|[a-z]+) (AND|OR) ([a-z]+) -> ([a-z]+)"); Regex regexShift = new Regex(@"([a-z]+) (L|R)SHIFT (\d+) -> ([a-z]+)"); Regex regexNot = new Regex(@"^NOT ([a-z]+) -> ([a-z]+)"); string line; while ((line = reader.ReadLine()) != null) { Gate gate = new Gate(); MatchCollection matches = regexSetPass.Matches(line); GroupCollection groups; int i = 1; if (matches.Count > 0) { groups = matches[0].Groups; string s1 = groups[i++].Value; if (int.TryParse(s1, out gate.immediate)) { gate.operation = LogicOp.Set; } else { gate.operation = LogicOp.Bypass; gate.in1 = s1; } } else if ((matches = regexAndOr.Matches(line)).Count > 0) { groups = matches[0].Groups; string s1 = groups[i++].Value; string s2 = groups[i++].Value; if (int.TryParse(s1, out gate.immediate)) { gate.operation = LogicOp.Andi; } else { gate.in2 = s1; gate.operation = (s2 == "AND") ? LogicOp.And : LogicOp.Or; } gate.in1 = groups[i++].Value; } else if ((matches = regexShift.Matches(line)).Count > 0) { groups = matches[0].Groups; gate.in1 = groups[i++].Value; gate.operation = (groups[i++].Value == "L") ? LogicOp.Lshift : LogicOp.Rshift; gate.immediate = int.Parse(groups[i++].Value); } else if ((matches = regexNot.Matches(line)).Count > 0) { groups = matches[0].Groups; gate.in1 = groups[i++].Value; gate.operation = LogicOp.Not; } else { throw new ArgumentOutOfRangeException(); } gate.id = groups[i++].Value; list.Add(gate); } return(list); }
static Dictionary <string, int> ExecuteGates(List <Gate> gatesIn) { List <Gate> gates = new List <Gate>(gatesIn); Dictionary <string, int> states = new Dictionary <string, int>(); int oldGates; do { for (int i = 0; i < gates.Count; i++) { Gate g = gates[i]; bool b1 = (g.in1 == null) ? false : states.ContainsKey(g.in1); bool b2 = (g.in2 == null) ? false : states.ContainsKey(g.in2); int in1 = b1 ? states[g.in1] : 0; int in2 = b2 ? states[g.in2] : 0; if (g.operation == LogicOp.Set) { states[g.id] = g.immediate; gates[i] = null; } else if ((g.operation == LogicOp.Andi) && b1) { states[g.id] = in1 & g.immediate; gates[i] = null; } else if ((g.operation == LogicOp.Not) && b1) { states[g.id] = 65535 ^ in1; gates[i] = null; } else if ((g.operation == LogicOp.Lshift) && b1) { states[g.id] = in1 << g.immediate; gates[i] = null; } else if ((g.operation == LogicOp.Rshift) && b1) { states[g.id] = in1 >> g.immediate; gates[i] = null; } else if ((g.operation == LogicOp.Bypass) && b1) { states[g.id] = in1; gates[i] = null; } else if ((g.operation == LogicOp.And) && b1 && b2) { states[g.id] = in1 & in2; gates[i] = null; } else if ((g.operation == LogicOp.Or) && b1 && b2) { states[g.id] = in1 | in2; gates[i] = null; } } oldGates = gates.Count; gates = gates.Where(x => x != null).ToList(); }while ((gates.Count > 0)); // && (gates.Count != oldGates)); return(states); }