Parser.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using System.Text.RegularExpressions;
  2. namespace Day20;
  3. public partial class Parser
  4. {
  5. [GeneratedRegex(@"(broadcaster|([%&-])(\w+)) -> (.*)")]
  6. private partial Regex LineMatch();
  7. public SignalProcessor Parse(string inputFile)
  8. {
  9. using var reader = File.OpenText(inputFile);
  10. var modules = new Dictionary<string, (Module m, string[] outputs)>();
  11. while (!reader.EndOfStream)
  12. {
  13. var line = reader.ReadLine()!;
  14. var match = LineMatch().Match(line);
  15. if (!match.Success)
  16. {
  17. throw new Exception($"Unable to parse line {line}");
  18. }
  19. Module? module;
  20. if (match.Groups[1].Value == "broadcaster")
  21. {
  22. module = new BroadcastModule("broadcaster");
  23. modules["broadcaster"] = (module, GetOutputs(match));
  24. }
  25. else
  26. {
  27. if (match.Groups[2].Value == "%")
  28. {
  29. module = new FlipFlopModule(match.Groups[3].Value);
  30. }
  31. else if (match.Groups[2].Value == "&")
  32. {
  33. module = new ConjunctionModule(match.Groups[3].Value);
  34. }
  35. else if (match.Groups[2].Value == "-")
  36. {
  37. module = new SinkModule(match.Groups[3].Value);
  38. }
  39. else
  40. {
  41. throw new Exception($"Unknown module type: {match.Groups[2].Value}");
  42. }
  43. modules[match.Groups[3].Value] = (module, GetOutputs(match));
  44. }
  45. }
  46. return new SignalProcessor(modules);
  47. }
  48. private static string[] GetOutputs(Match match)
  49. {
  50. return match.Groups[4].Value
  51. .Split(',', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
  52. .ToArray();
  53. }
  54. }