| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- using System.Text.RegularExpressions;
- namespace Day19;
- public partial class Rule
- {
- [GeneratedRegex(@"(\w)([<>])(\d+):(\w+)|(\w+)")]
- private partial Regex ItemMatch();
- private readonly IList<IRuleItem> _items;
- public Rule(string ruleText)
- {
- _items = ItemMatch().Matches(ruleText).Select<Match, IRuleItem>(m =>
- {
- if (m.Groups[5].Length > 0)
- {
- return new Terminal(m.Groups[5].Value);
- }
-
- return new Item(m.Groups[1].Value, m.Groups[2].Value, int.Parse(m.Groups[3].Value), m.Groups[4].Value);
- }).ToList();
- }
- public string Apply(Part p)
- {
- foreach (var item in _items)
- {
- //Console.WriteLine(item);
- var next = item.Apply(p);
- //Console.WriteLine($"=> {next}");
- if (next != null)
- {
- return next;
- }
- }
- throw new Exception("Rule should always match");
- }
-
- private interface IRuleItem
- {
- string? Apply(Part p);
- }
- private class Item : IRuleItem
- {
- private readonly string _property;
- private readonly string _op;
- private readonly int _value;
- private readonly string _next;
- public Item(string property, string op, int value, string next)
- {
- _property = property;
- _op = op;
- _value = value;
- _next = next;
- }
- public string? Apply(Part p)
- {
- if (_op == "<")
- {
- return p.Get(_property) < _value ? _next : null;
- }
- if (_op == ">")
- {
- return p.Get(_property) > _value ? _next : null;
- }
- return null;
- }
- public override string ToString()
- {
- return $"{_property} {_op} {_value} : {_next}";
- }
- }
-
- private class Terminal : IRuleItem
- {
- private readonly string _next;
- public Terminal(string next)
- {
- _next = next;
- }
- public string? Apply(Part p)
- {
- return _next;
- }
- public override string ToString()
- {
- return $"Terminal<{_next}>";
- }
- }
- }
|