| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- 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;
- }
- }
- }
- }
|