public void Test(int treeDepth, string[] nodeProducingRuleToSymbols, string[] expectedProducedSymbols) { SymbolsSet<int> s = new SymbolsSet<int>(new [] { new Symbol<int>("Node0"), new Symbol<int>("Node1"), new Symbol<int>("Node2"), new Symbol<int>("Node") }); // Node -> Node0|Node1|Node2 nodeProducingRuleToSymbols = nodeProducingRuleToSymbols ?? new [] {"Node0", "Node1", "Node2"}; OrRule<int> nodeProducingRule = new OrRule<int>(s["Node"], nodeProducingRuleToSymbols.Select(n => s[n])); TreeBuilder<int> treeBuilder = new TreeBuilder<int>(); TreeGeneratingRuleSelector<int> ruleSelector = new TreeGeneratingRuleSelector<int>(treeDepth, treeBuilder, nodeProducingRule.Rules); List<string> producedSymbols = new List<string>(); while(!treeBuilder.IsTreeReady) { Rule<int> rule = ruleSelector.Next(); string sn = rule.Produce().First().Name; int v = int.Parse(sn.Replace("Node", "")); treeBuilder.Append(v, v); producedSymbols.Add(sn); } Assert.AreElementsEqual(expectedProducedSymbols, producedSymbols); }
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())); }
private static (IDictionary <string, Rule>, List <string>) Parse(List <string> lines) { var rules = new Dictionary <string, Rule>(); var messages = new List <string>(); foreach (var line in lines) { if (OrRule.MatchesRuleDescription(line)) { var rule = OrRule.Parse(line); rules.Add(rule.Id, rule); } else if (MatchRule.MatchesRuleDescription(line)) { MatchRule matchRule = MatchRule.Parse(line); rules.Add(matchRule.Id, matchRule); } else if (SequenceRule.MatchesRuleDescription(line)) { SequenceRule sequenceRule = SequenceRule.Parse(line); rules.Add(sequenceRule.Id, sequenceRule); } else if (!string.IsNullOrEmpty(line)) { messages.Add(line); } } return(rules, messages); }
/// <summary> /// Parses the validation rule definitions /// </summary> /// <param name="ruleDefinitions">The definitions for the validation rules</param> /// <returns>The list of IRule instances</returns> private static Dictionary <int, IRule> ParseRules(string[] ruleDefinitions) { var rules = new Dictionary <int, IRule>(); foreach (string rule in ruleDefinitions) { var parts = rule.Split(':'); int num = int.Parse(parts[0]); if (parts[1].Contains('"')) { rules[num] = new ConstantRule(parts[1].Trim().Trim('"')[0]); } else if (parts[1].Contains('|')) { var orRule = new OrRule(); parts = parts[1].Split('|'); orRule.Left = ParseSequence(parts[0]); orRule.Right = ParseSequence(parts[1]); rules[num] = orRule; } else { rules[num] = ParseSequence(parts[1]); } } return(rules); }
/// <summary> /// Executes part 2 of the puzzle /// </summary> /// <param name="ruleDefinitions">The definitions for the validation rules</param> /// <param name="messages">The messages to validate</param> /// <returns>The number of valid messages</returns> private static int ExecutePart2(string[] ruleDefinitions, string[] messages) { var rules = ParseRules(ruleDefinitions); rules[8] = new OrRule(rules[8], new SequenceRule(42, 8)); rules[11] = new OrRule(rules[11], new SequenceRule(42, 11, 31)); return(Execute(rules, messages)); }
public void TestOrRule() { var rule = new OrRule(new StringRule("cat"), new StringRule("dog")); Assert.IsFalse(rule.Match("something")); Assert.IsFalse(rule.Match("fishcatdog")); Assert.IsTrue(rule.Match("catfish")); Assert.IsTrue(rule.Match("dogfish")); }
public void CheckRuleType() { Rule r = new OrRule(); Assert.AreEqual("Or", r.RuleType); r = new ScheduleRule(); Assert.AreEqual("Schedule", r.RuleType); r = new UserSelectionRule(); Assert.AreEqual("UserSelection", r.RuleType); }
private static int MatchesRule0Cyclic(List <string> lines) { var(newRules, messages) = Parse(lines); newRules["8"] = OrRule.Parse("8: 42 | 42 8"); newRules["11"] = OrRule.Parse("11: 42 31 | 42 11 31"); var result = messages.Count(message => newRules["0"].IsValid(message, newRules)); return(result); }
public FeatureFlagState OrRule(FeatureFlagState p1, FeatureFlagState p2) { var or = new OrRule { Rules = new Rule[] { new ConstantRule { Value = p1 }, new ConstantRule { Value = p2 } } }; return(or.Evaluate(null)); }
protected override string SolvePartTwo() { var parse = ParseInput(); rules = parse.Item1; rules[8] = OrRule.Parse("42 | 42 8"); rules[11] = OrRule.Parse("42 31 | 42 11 31"); var lines = parse.Item2; return(lines.Select(x => Tuple.Create(x, rules[0].Match(x))).Where(x => x.Item2.Length > 0 && x.Item2.Any(y => y == x.Item1.Length - 1)).Count().ToString()); }
public void NotValidIfAllRuleFails() { var m1 = "r1 message"; var m2 = "r2 message"; var r1 = new Mock<IRule<int>>(); var r2 = new Mock<IRule<int>>(); r1.Setup(r => r.IsValid(It.IsAny<int>())).Returns(false); r1.Setup(r => r.Message).Returns(m1); r2.Setup(r => r.IsValid(It.IsAny<int>())).Returns(false); r2.Setup(r => r.Message).Returns(m2); var combination = new OrRule<int>(new List<IRule<int>> { r1.Object, r2.Object }); var candidate = combination.IsValid(2); Assert.IsFalse(candidate); Assert.AreEqual(m1 + Environment.NewLine + m2 + Environment.NewLine, combination.Message); r1.Verify(r => r.IsValid(It.IsAny<int>()), Times.Once()); r2.Verify(r => r.IsValid(It.IsAny<int>()), Times.Once()); }
protected override string DescribeOrRule(OrRule <T> rule) { var leftDescription = Describe(rule.Left); if (NeedsParenthesis(rule, rule.Left)) { leftDescription = string.Format("({0})", leftDescription); } var rightDescription = Describe(rule.Right); if (NeedsParenthesis(rule, rule.Right)) { rightDescription = string.Format("({0})", rightDescription); } return(string.Format("{0} OR {1}", leftDescription, rightDescription)); }
protected override string DescribeOrRule(OrRule <T> rule) { var result = DescribeResult(rule.IsTrueFor(evaluateWith)); var leftDescription = Describe(rule.Left); if (NeedsParenthesis(rule, rule.Left)) { leftDescription = string.Format("({0})", leftDescription); } var rightDescription = Describe(rule.Right); if (NeedsParenthesis(rule, rule.Right)) { rightDescription = string.Format("({0})", rightDescription); } return(string.Format("{0} OR[{2}] {1}", leftDescription, rightDescription, result)); }
public void IsValidIfAnyRulesAreValid() { var msg = "r2 message"; var r1 = new Mock<IRule<int>>(); var r2 = new Mock<IRule<int>>(); var r3 = new Mock<IRule<int>>(); r1.Setup(r => r.IsValid(It.IsAny<int>())).Returns(false); r1.Setup(r => r.Message).Returns(msg); r2.Setup(r => r.IsValid(It.IsAny<int>())).Returns(true); r3.Setup(r => r.IsValid(It.IsAny<int>())).Returns(true); var combination = new OrRule<int>(new List<IRule<int>> { r1.Object, r2.Object, r3.Object }); var candidate = combination.IsValid(2); Assert.IsTrue(candidate); Assert.AreEqual(msg + Environment.NewLine, combination.Message); r1.Verify(r => r.IsValid(It.IsAny<int>()), Times.Once()); r2.Verify(r => r.IsValid(It.IsAny<int>()), Times.Once()); // Proves short-circuit evaluation r3.Verify(r => r.IsValid(It.IsAny<int>()), Times.Never()); }
static IRule CompileNodeForRule(string ruletext, Dictionary <int, RuleCacheItem> ruleSet) { Function Head, BuildingRule; Head = BuildingRule = new AndRule(); foreach (var item in ruletext.Split(' ')) { if (item.Contains("\"")) { var nodeToAdd = new StringRule { toMatch = item[1] };; //Comment this line for multi string rule support return(nodeToAdd); BuildingRule.AddNode(nodeToAdd); } else if (item.Contains("|")) { //Split on left and right Head = new OrRule(); Head.AddNode(BuildingRule); BuildingRule = new AndRule(); Head.AddNode(BuildingRule); } else { var childToExplore = int.Parse(item); //Check if the cached copy hasn't compiled yet and compile it if (ruleSet[childToExplore].CachedRule == null) { ruleSet[childToExplore].CachedRule = CompileNodeForRule(ruleSet[childToExplore].Text, ruleSet); } BuildingRule.AddNode(ruleSet[childToExplore].CachedRule); } } return(Head); }
public void NotValidIfAllRuleFails() { var m1 = "r1 message"; var m2 = "r2 message"; var r1 = new Mock <IRule <int> >(); var r2 = new Mock <IRule <int> >(); r1.Setup(r => r.IsValid(It.IsAny <int>())).Returns(false); r1.Setup(r => r.Message).Returns(m1); r2.Setup(r => r.IsValid(It.IsAny <int>())).Returns(false); r2.Setup(r => r.Message).Returns(m2); var combination = new OrRule <int>(new List <IRule <int> > { r1.Object, r2.Object }); var candidate = combination.IsValid(2); Assert.IsFalse(candidate); Assert.AreEqual(m1 + Environment.NewLine + m2 + Environment.NewLine, combination.Message); r1.Verify(r => r.IsValid(It.IsAny <int>()), Times.Once()); r2.Verify(r => r.IsValid(It.IsAny <int>()), Times.Once()); }
public void InitInput(string content) { var splitContent = content.Split(new string[] { "\r\n" }, StringSplitOptions.None); bool doProposals = false; foreach (var currentLine in splitContent) { if (string.IsNullOrEmpty(currentLine)) { doProposals = true; } else if (doProposals) { _proposals.Add(currentLine); } else { var s = currentLine.Split(new string[] { ": " }, StringSplitOptions.RemoveEmptyEntries); var ruleNum = int.Parse(s[0]); if (s[1].Contains('\"')) { _rules[ruleNum] = new CharacterRule(s[1].Trim('\"'), ruleNum); continue; } if (s[1].Contains(('|'))) { var split = s[1].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries); _rules[ruleNum] = new OrRule(CreateThenRule(split[0], -1), CreateThenRule(split[1], -1), ruleNum); } else { _rules[ruleNum] = CreateThenRule(s[1], ruleNum); } } } }
public void IsValidIfAnyRulesAreValid() { var msg = "r2 message"; var r1 = new Mock <IRule <int> >(); var r2 = new Mock <IRule <int> >(); var r3 = new Mock <IRule <int> >(); r1.Setup(r => r.IsValid(It.IsAny <int>())).Returns(false); r1.Setup(r => r.Message).Returns(msg); r2.Setup(r => r.IsValid(It.IsAny <int>())).Returns(true); r3.Setup(r => r.IsValid(It.IsAny <int>())).Returns(true); var combination = new OrRule <int>(new List <IRule <int> > { r1.Object, r2.Object, r3.Object }); var candidate = combination.IsValid(2); Assert.IsTrue(candidate); Assert.AreEqual(msg + Environment.NewLine, combination.Message); r1.Verify(r => r.IsValid(It.IsAny <int>()), Times.Once()); r2.Verify(r => r.IsValid(It.IsAny <int>()), Times.Once()); // Proves short-circuit evaluation r3.Verify(r => r.IsValid(It.IsAny <int>()), Times.Never()); }
static void Main(string[] args) { var r1 = new EqualRule(); r1.AttributeName = "a1"; r1.TargetValue.Add("test1"); var r2 = new EqualRule(); r2.AttributeName = "b2"; r2.TargetValue.Add("test2"); r2.TargetValue.Add("test2bis"); var r3 = new EqualRule(); r3.AttributeName = "c3"; r3.TargetValue.Add("test3"); var r4 = new NotEqualRule(); r4.AttributeName = "c4"; r4.TargetValue.Add("test4"); var r5 = new EqualRule(); r5.AttributeName = "or5"; r5.TargetValue.Add("test5"); var r6 = new EqualRule(); r6.AttributeName = "or6"; r6.TargetValue.Add("test6"); var orRule = new OrRule(); orRule.ChildRules.Add(r5); orRule.ChildRules.Add(r6); var andRule = new AndRule(); andRule.ChildRules.Add(r1); andRule.ChildRules.Add(r2); andRule.ChildRules.Add(r3); andRule.ChildRules.Add(r4); andRule.ChildRules.Add(orRule); var rc = new RuleContainer(); rc.MetadataInputs.Add(new MetadataEntity() { AttributeName = "a1", AttributeType = typeof(string) }); rc.MetadataInputs.Add(new MetadataEntity() { AttributeName = "b2", AttributeType = typeof(string) }); rc.MetadataInputs.Add(new MetadataEntity() { AttributeName = "c3", AttributeType = typeof(string) }); rc.MetadataInputs.Add(new MetadataEntity() { AttributeName = "c4", AttributeType = typeof(string) }); rc.MetadataInputs.Add(new MetadataEntity() { AttributeName = "or5", AttributeType = typeof(string) }); rc.MetadataInputs.Add(new MetadataEntity() { AttributeName = "or6", AttributeType = typeof(string) }); rc.Rules.Add(andRule); rc.ReturnValue = "false"; rc.CompileExpression(); var res1 = rc.CompiledFunction(new string[] { "test1", "test2", "test3", "test4444", "test5fdsfsd", "test6" }); }
protected override string DescribeOrRule(OrRule <T> rule) { return(string.Format("({0} OR {1})", Describe(rule.Left), Describe(rule.Right))); }
private Rule Interpret(Grammar grammar, ISemanticNode node) { Rule rule = null; if (node is BranchSemanticNode branch) { switch ((EbnfNodeType)branch.NodeType) { case EbnfNodeType.Group: rule = Interpret(grammar, branch.Children[0]); break; case EbnfNodeType.Repeat: rule = new RepeatRule(grammar, Interpret(grammar, branch.Children[0])); break; case EbnfNodeType.Optional: rule = new OptionalRule(grammar, Interpret(grammar, branch.Children[0])); break; case EbnfNodeType.Not: rule = new NotRule(grammar, Interpret(grammar, branch.Children[0])); break; case EbnfNodeType.And: rule = new AndRule(grammar, branch.Children.Select(child => Interpret(grammar, child))); break; case EbnfNodeType.Or: rule = new OrRule(grammar, branch.Children.Select(child => Interpret(grammar, child))); break; case EbnfNodeType.None: rule = Interpret(grammar, branch.Children.Single()); break; case EbnfNodeType.Root: case EbnfNodeType.Rule: case EbnfNodeType.Token: default: throw new Exception(); } } else if (node is LeafSemanticNode leaf) { switch ((EbnfNodeType)leaf.NodeType) { case EbnfNodeType.Identifier: rule = grammar.ReferenceRule(leaf.Value); break; case EbnfNodeType.String: case EbnfNodeType.Regex: break; default: throw new Exception(); } } if (rule == null) { throw new Exception(); } else { return(rule); } }
public virtual void Visit(OrRule visitee) => Visit((CompositeRule)visitee);
public static void DoWork(string[] lines) { Dictionary <int, IRule> rules = new(); List <string> stringsToTest = new(); { bool doRules = true; foreach (var line in lines) { if (string.IsNullOrWhiteSpace(line)) { doRules = false; continue; } if (doRules) { var split1 = line.Split(":"); int ruleNumber = int.Parse(split1[0]); string ruleData = split1[1]; if (ruleData.Contains("\"")) { var ruleChar = ruleData.Replace("\"", "").Trim()[0]; rules.Add(ruleNumber, new CharRule(ruleChar)); } else if (ruleData.Contains("|")) { var sides = ruleData.Split("|"); var leftSide = sides[0].Trim().Split(" ").Select(x => int.Parse(x)).ToList(); var left = new MultiRefRule(leftSide.Select(x => new RefRule(x)).ToArray()); var rightSide = sides[1].Trim().Split(" ").Select(x => int.Parse(x)).ToList(); var right = new MultiRefRule(rightSide.Select(x => new RefRule(x)).ToArray()); rules.Add(ruleNumber, new OrRule(left, right)); } else { var ruleDatas = ruleData.Trim().Split(" ").Select(x => int.Parse(x)).ToList(); if (ruleDatas.Count == 1) { rules.Add(ruleNumber, new RefRule(ruleDatas[0])); } else { rules.Add( ruleNumber, new MultiRefRule(ruleDatas.Select(x => new RefRule(x)).ToArray())); } } } else { stringsToTest.Add(line); } } } //part1 { var count = 0; foreach (var test in stringsToTest) { var rule = new StartRule(); var result = rule.Eval(test.ToCharArray().AsSpan(), rules); if (result.match) { count++; } //Console.WriteLine(result); } Console.WriteLine(count); } //part2 { // Cheating: ok something is wrong with checking stuff at the end of the string. Resulting at false positives. Fail. //8: 42 | 42 8 //11: 42 31 | 42 11 31 rules[8] = new OrRule(new RefRule(42), new MultiRefRule(new[] { new RefRule(42), new RefRule(8) })); rules[11] = new OrRule( new MultiRefRule(new[] { new RefRule(42), new RefRule(31) }), new MultiRefRule(new[] { new RefRule(42), new RefRule(11), new RefRule(31) }) ); // foreach (var (number,rule) in rules.ToArray()) // { // rules[number] = Simplify(rule, number); // } IRule Simplify(IRule r, int index) { if (r is MultiRefRule multiRefRule) { var list = new List <IRule>(); foreach (var refRule in multiRefRule.RefRules) { if (refRule.RuleNumber == index) { list.Add(refRule); continue; } var nr = Simplify(refRule, refRule.RuleNumber); list.Add(nr); } int count = 0; foreach (var nr in list) { if (nr is CharRule cr) { count++; } if (nr is SolvedRule sr) { count++; } } if (count == list.Count) { var chArr = new List <char>(); foreach (var nr in list) { if (nr is CharRule cr) { chArr.Add(cr.Char); } if (nr is SolvedRule sr) { chArr.AddRange(sr.Chars); } } return(new SolvedRule(chArr.ToArray())); } } else if (r is RefRule refRule) { var nr = Simplify(rules[refRule.RuleNumber], refRule.RuleNumber); if (nr is CharRule cr) { return(cr); } if (nr is SolvedRule sr) { return(sr); } } else if (r is OrRule orRule) { return(new OrRule(Simplify(orRule.Left, index), Simplify(orRule.Right, index))); } return(r); } var count = 0; foreach (var test in stringsToTest) { var rule = new StartRule(); var result = rule.Eval(test.ToCharArray().AsSpan(), rules); if (result.match) { count++; } // Console.WriteLine($"{result} : {test}"); } Console.WriteLine(count); } }
protected override string DescribeOrRule(OrRule <T> rule) { var result = DescribeResult(rule.IsTrueFor(evaluateWith)); return(string.Format("({0} OR {1})[{2}]", Describe(rule.Left), Describe(rule.Right), result)); }
protected abstract string DescribeOrRule(OrRule <T> rule);