using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace D07._1 { public class Program { public interface In { } public class Wire : In { public string Name; } public class Signal : In { public ushort Value; } public class Gate { public In L1; public In L2; public Wire R; public string Op; } public static Signal TestCircuit(List gates, Gate gate) { if (gate.Op is null && gate.L1 is Signal s) return s; if (gate.L1 is Wire w1) { var l1g = gates.Where(g => g.R.Name == w1.Name).First(); gate.L1 = TestCircuit(gates, l1g); } if (gate.L2 is Wire w2) { var l2g = gates.Where(g => g.R.Name == w2.Name).First(); gate.L2 = TestCircuit(gates, l2g); } if (gate.R.Name == "a") return gate.L1 as Signal; if (gate.R.Name == "b") return new Signal() { Value = 956 }; var result = operators[gate.Op]((gate.L1 as Signal)?.Value, (gate.L2 as Signal).Value); return new Signal() { Value = result }; } static Dictionary> operators = new Dictionary> { { "AND", (a, b) => (ushort)(a & b) }, { "OR", (a, b) => (ushort)(a | b) }, { "NOT", (a, b) => (ushort)(~ b) }, { "LSHIFT", (a, b) => (ushort)(a << b) }, { "RSHIFT", (a, b) => (ushort)(a >> b) } }; static void Main(string[] args) { if (args.Length < 1) throw new ArgumentException(); if (File.Exists(args[0]) == false) throw new FileNotFoundException(); Signal answer = TestSignalP1(args[0]); Console.WriteLine($"The answer is : {answer.Value}"); } public static Signal TestSignalP1(string file) { List gates = new List(); ParseFile(file, gates); var last = gates.Where(g => g.R.Name == "a").First(); var answer = TestCircuit(gates, last); return answer; } public static void ParseFile(string f, List gates) { using (var file = File.OpenText(f)) { while (true) { var line = file.ReadLine(); if (line == null) break; ParseLine(gates, line); } } } private static void ParseLine(List gates, string line) { var sp = line.Split(" -> "); string lpart = sp[0], rpart = sp[1]; bool hasOp = false; In L1 = null, L2 = null; var gate = new Gate(); SearchOperator(operators, line, lpart, ref hasOp, ref L1, ref L2, gate); if (hasOp == false) { if (ushort.TryParse(lpart, out ushort lv)) { L1 = new Signal() { Value = lv }; } else { L1 = new Wire() { Name = lpart }; } gate.L1 = L1; } var R = new Wire() { Name = rpart }; gate.R = R; gates.Add(gate); } private static void SearchOperator(Dictionary> operators, string line, string lpart, ref bool hasOp, ref In L1, ref In L2, Gate gate) { foreach (var op in operators) { if (line.Contains(op.Key) == false) continue; hasOp = true; var lop = lpart.Split(op.Key); var a = lop[0].Trim(' '); var b = lop[1].Trim(' '); if (ushort.TryParse(a, out ushort aa)) { L1 = new Signal() { Value = aa }; } else if (a != string.Empty) { L1 = new Wire() { Name = a }; } if (ushort.TryParse(b, out ushort bb)) { L2 = new Signal() { Value = bb }; } else { L2 = new Wire() { Name = b }; } gate.L1 = L1; gate.L2 = L2; gate.Op = op.Key; break; } } } }