public void Puzzle_19B()
            {
                var detector = new SeaMonsterDetector();

                detector.BuildRules(PuzzleRulesInput
                                    .Select(x => x.StartsWith("8:") ? "8: 42 | 42 +" : x)
                                    .Select(x => x.StartsWith("11:") ? "11: 42 31" +
                                            " | 42 42 31 31" +
                                            " | 42 42 42 31 31 31" +
                                            " | 42 42 42 42 31 31 31 31"          /*+
                                                                                   * " | 42 42 42 42 42 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 31 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 42 31 31 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 42 42 31 31 31 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 42 42 42 31 31 31 31 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 42 42 42 42 31 31 31 31 31 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 42 42 42 42 42 31 31 31 31 31 31 31 31 31 31 31 31" +
                                                                                   * " | 42 42 42 42 42 42 42 42 42 42 42 42 42 31 31 31 31 31 31 31 31 31 31 31 31 31"*/
                        : x)
                                    .ToArray());

                var ok = PuzzleDataInput.Sum(s => detector.TestStringWithRule(s, 0) ? 1 : 0);

                Assert.True(394 > ok, "too high");
                Assert.Equal(389, ok);
            }
            public void Example_1()
            {
                var inputs = new[]
                {
                    "0: 4 1 5",
                    "1: 2 3 | 3 2",
                    "2: 4 4 | 5 5",
                    "3: 4 5 | 5 4",
                    "4: \"a\"",
                    "5: \"b\""
                };

                var detector = new SeaMonsterDetector();

                detector.BuildRules(inputs);

                var strings = new[]
                {
                    "ababbb",
                    "bababa",
                    "abbbab",
                    "aaabbb",
                    "aaaabbb"
                };

                var ok = strings.Sum(s => detector.TestStringWithRule(s, 0) ? 1 : 0);

                Assert.Equal(2, ok);
            }
            public void Puzzle_19A()
            {
                var detector = new SeaMonsterDetector();

                detector.BuildRules(PuzzleRulesInput);

                var ok = PuzzleDataInput.Sum(s => detector.TestStringWithRule(s, 0) ? 1 : 0);

                Assert.Equal(184, ok);
            }
            public void Should_set_up_basic_non_referenced_rules()
            {
                var detector = new SeaMonsterDetector();

                detector.BuildRules(new [] { "0: \"a\"", "1: \"b\"" });

                Assert.Equal(2, detector.Rules.Count);
                Assert.Equal("a", detector.Rules[0].Regex);
                Assert.Equal("b", detector.Rules[1].Regex);
            }
            public void Should_set_up_referenced_or_rules()
            {
                var inputs = new[]
                {
                    "0: 1 | 2",
                    "1: \"a\"",
                    "2: \"b\""
                };

                var detector = new SeaMonsterDetector();

                detector.BuildRules(inputs);

                Assert.Equal(3, detector.Rules.Count);
                Assert.Equal("(a)|(b)", detector.Rules[0].Regex);
                Assert.Equal("a", detector.Rules[1].Regex);
                Assert.Equal("b", detector.Rules[2].Regex);
            }
            public void Should_set_up_infinite_referenced_rules()
            {
                var inputs = new[]
                {
                    "0: 1 2",
                    "1: \"a\"",
                    "2: 1 3 | 3 1",
                    "3: \"b\""
                };

                var detector = new SeaMonsterDetector();

                detector.BuildRules(inputs);

                Assert.Equal(4, detector.Rules.Count);
                Assert.Equal("(a)((a)(b)|(b)(a))", detector.Rules[0].Regex);
                Assert.Equal("a", detector.Rules[1].Regex);
                Assert.Equal("(a)(b)|(b)(a)", detector.Rules[2].Regex);
                Assert.Equal("b", detector.Rules[3].Regex);
            }
            public void Example_2()
            {
                var inputs = new[]
                {
                    "42: 9 14 | 10 1",
                    "9: 14 27 | 1 26",
                    "10: 23 14 | 28 1",
                    "1: \"a\"",
                    "11: 42 31",
                    "5: 1 14 | 15 1",
                    "19: 14 1 | 14 14",
                    "12: 24 14 | 19 1",
                    "16: 15 1 | 14 14",
                    "31: 14 17 | 1 13",
                    "6: 14 14 | 1 14",
                    "2: 1 24 | 14 4",
                    "0: 8 11",
                    "13: 14 3 | 1 12",
                    "15: 1 | 14",
                    "17: 14 2 | 1 7",
                    "23: 25 1 | 22 14",
                    "28: 16 1",
                    "4: 1 1",
                    "20: 14 14 | 1 15",
                    "3: 5 14 | 16 1",
                    "27: 1 6 | 14 18",
                    "14: \"b\"",
                    "21: 14 1 | 1 14",
                    "25: 1 1 | 1 14",
                    "22: 14 14",
                    "8: 42",
                    "26: 14 22 | 1 20",
                    "18: 15 15",
                    "7: 14 5 | 1 21",
                    "24: 14 1"
                };

                var detector = new SeaMonsterDetector();

                detector.BuildRules(inputs
                                    .Select(x => x.StartsWith("8:") ? "8: 42 | 42 +" : x)
                                    .Select(x => x.StartsWith("11:") ? "11: 42 31" +
                                            " | 42 42 31 31" +
                                            " | 42 42 42 31 31 31" +
                                            " | 42 42 42 42 31 31 31 31"
                        : x)
                                    .ToArray());

                var strings = new[]
                {
                    "abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa",
                    "bbabbbbaabaabba",
                    "babbbbaabbbbbabbbbbbaabaaabaaa",
                    "aaabbbbbbaaaabaababaabababbabaaabbababababaaa",
                    "bbbbbbbaaaabbbbaaabbabaaa",
                    "bbbababbbbaaaaaaaabbababaaababaabab",
                    "ababaaaaaabaaab",
                    "ababaaaaabbbaba",
                    "baabbaaaabbaaaababbaababb",
                    "abbbbabbbbaaaababbbbbbaaaababb",
                    "aaaaabbaabaaaaababaa",
                    "aaaabbaaaabbaaa",
                    "aaaabbaabbaaaaaaabbbabbbaaabbaabaaa",
                    "babaaabbbaaabaababbaabababaaab",
                    "aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba"
                };

                var ok = strings.Sum(s => detector.TestStringWithRule(s, 0) ? 1 : 0);

                Assert.Equal(12, ok);
            }