static bool Детерминированный(string word) {
            var rules = new[] { -1, -1, 3, 3, 6, 7, 6, 9, 7, 9, 11, 11 }
               .Select((t, i) => new Rule(i.ToString(), 'a', t.ToString()))
               .Concat(new[] { 1, 2, 4, 5, 4, 5, 8, 8, 5, 10, -1, 12 }
               .Select((t, i) => new Rule(i.ToString(), 'b', t.ToString())))
               .Concat(new[] { new Rule(STR, EPS, "0") }).ToList();

            var gotEnd = false;
            try {
                new Automaton(new[] {
                    new Final(state => { gotEnd = true; throw new Exception(); }, "8", "10", "12")
                }, rules).Run(word);
            } catch { /**/ }
            return gotEnd;
        }

        static bool Недетерминированный(string word) {
            var rules = new[] {
                new Rule(STR, 'b', STR),
                new Rule(STR, 'b', '1'),
                new Rule('1', 'b', '2'),
                new Rule('2', 'a', '2'),
                new Rule('2', EPS, '3'),
                new Rule('3', 'a', '4'),
                new Rule('3', 'b', '5'),
                new Rule('3', EPS, '6'),
                new Rule('4', 'b', '5'),
                new Rule('5', EPS, '3'),
                new Rule('6', 'a', '6'),
                new Rule('6', 'b', '7'),
                new Rule('7', 'a', '8'),
                new Rule('8', 'a', '8'),
                new Rule('8', 'b', '9'),
            };

            var gotEnd = false;
            try {
                new Automaton(new[] {
                    new Final(state => { if (gotEnd = word.Length == state.Position) throw new Exception(); }, "9")
                }, rules).Run(word);
            } catch { /**/ }
            return gotEnd;
        }
        static void Main(string[] args) {
            int count53150 = 0, count53555 = 0, count5510 = 0, count0001 = 0;

            var machine = new Automaton(
                new[] {
                    // final states
                    new Final(_ => count53150++, "A6"),
                    new Final(_ => count53555++, "B6"),
                    new Final(_ => count5510++, "C4"),
                    new Final(_ => count0001++, "D4"),
                }, rules);

            machine.Run("0001531505355510001");

            var @out = new[] { $"53150: {count53150}", $"53555: {count53555}", $"5510: {count5510}", $"0001: {count0001}" };
            Console.WriteLine(string.Join("\n", @out));

            if (Debugger.IsAttached) {
                Console.WriteLine("Press any key to continue...");
                Console.ReadKey();
            }
        }