public static Rule Parse(string input, int index) { int id = int.Parse(input.Substring(0, index)); input = input.Substring(index + 1).Trim(); Rule rule = null; if (input.StartsWith('\"')) { rule = new BaseRule(id, input); } else { index = input.IndexOf('|'); if (index >= 0) { rule = new MultiRule(id, input); } else { rule = new StandardRule(id, input, -1); } } return(rule); }
protected override bool match2(Dictionary <int, Rule> rules, string message, ref int index) { //To match this rule in Part2, each looping rule is matched as many times as possible before returning if (ID == 0) { //Assume rule 0 only has 2 rules MultiRule rule1 = (MultiRule)rules[requiredRules[0]]; MultiRule rule2 = (MultiRule)rules[requiredRules[1]]; for (int firstRuleMatches = 0; ; firstRuleMatches++) { index = 0; if (!rule1.matchLooping(rules, message, ref index, firstRuleMatches)) { if (index >= message.Length) { return(false); } else { continue; //Try more!!! } } int baseIndex = index; for (int secondRuleMatches = 0; ; secondRuleMatches++) { index = baseIndex; //Reset the index to the end of rule1 matches if (rule2.matchLooping(rules, message, ref index, secondRuleMatches)) { if (index == message.Length) { return(true); } } else { if (index >= message.Length) { break; } else { continue; } } } } } else { bool result = true; foreach (int ruleId in requiredRules) { if (!rules[ruleId].match2(rules, message, ref index)) { result = false; } } return(result); } }
public Tuple <Dictionary <int, Rule>, string[]> ParseInput() { var lines = Input.Split("\n", StringSplitOptions.TrimEntries); var i = 0; var rules = new Dictionary <int, Rule>(); while (!string.IsNullOrEmpty(lines[i])) { var a = lines[i].Split(':', StringSplitOptions.TrimEntries); int r = int.Parse(a[0]); if (a[1].Contains('\"')) { rules[r] = BasicRule.Parse(a[1]); } else if (a[1].Contains('|')) { rules[r] = OrRule.Parse(a[1]); } else { rules[r] = MultiRule.Parse(a[1]); } i++; } return(Tuple.Create(rules, lines.Skip(i + 1).ToArray())); }
static Rule[] ParseRules(IEnumerable <string> ruleText) { int maxRule = ruleText.Max(line => int.Parse(line.Substring(0, line.IndexOf(':')))); Rule[] rules = new Rule[maxRule + 1]; var defRegex = new Regex(@"^([0-9]+): (.*)$"); var charRegex = new Regex(@"""(\w)"""); var followingRegex = new Regex(@"( [0-9]+)+"); foreach (string line in ruleText) { var outline = defRegex.Match(line); int index = int.Parse(outline.Groups[1].Value); string body = outline.Groups[2].Value; var charMatch = charRegex.Match(body); if (charMatch.Success) { rules[index] = new LetterRule { Letter = charMatch.Groups[1].Value[0] }; continue; } var followMatch = followingRegex.Matches(line); if (!followMatch.Any()) { throw new Exception(); } var ruleIndices = followMatch .Select(match => match.Value.Split(" ", StringSplitOptions.RemoveEmptyEntries) .Select(int.Parse).ToArray()); var followRules = ruleIndices .Select <int[], Rule>(indices => new FollowingRules { RuleIndices = indices, Rules = rules }).ToArray(); if (followRules.Length == 1) { rules[index] = followRules[0]; } else { rules[index] = new MultiRule { Rules = followRules } }; } return(rules); }
public OrRule(MultiRule a, MultiRule b) { this.a = a; this.b = b; }