|
|
@@ -0,0 +1,170 @@
|
|
|
+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<Gate> 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<string, Func<ushort?, ushort, ushort>> operators = new Dictionary<string, Func<ushort?, ushort, ushort>>
|
|
|
+ {
|
|
|
+ { "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<Gate> gates = new List<Gate>();
|
|
|
+
|
|
|
+ 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<Gate> 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<Gate> 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<string, Func<ushort?, ushort, ushort>> 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|