protected override void WriteLine(string a_str, params object[] a_args)
        {
            String str = String.Format(a_str, a_args);

            base.WriteLine(a_str, a_args);
            m_pi.AddLine(str);
        }
        public void Test_Solution_Tress_Verificator()
        {
            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            FileInfo[] files = new DirectoryInfo(Directories.SolutionTrees).GetFiles(FileExtensions.XmlZipMask);

            string dir_diff = Directories.SolutionTrees + Path.DirectorySeparatorChar + "Verification_Failed";

            new DirectoryInfo(dir_diff).CreateOrEmpty();

            bool ok = true;

            ConcurrentCounter counter = new ConcurrentCounter();
            int index = 0;

            Parallel.ForEach(files, (file) =>
            {
                counter.Increment();
                pi.AddLine((counter.Value * 100 / files.Length).ToString());

                SudokuSolutionNode node = SudokuSolutionNode.LoadFromFile(file.FullName);

                foreach (SudokuSolutionNode n in node.GetAllNodesEnumerator())
                {
                    if (n.State == SudokuSolutionNodeState.Solution)
                    {
                        SudokuVerificator verificator = new SudokuVerificator(n.Board);

                        foreach (SudokuNumber number in n.Solution.Removed)
                        {
                            bool b = verificator.IsImpossible(number.Col, number.Row, number.Number - 1);

                            if (!b)
                            {
                                ok = false;

                                string diff_file = String.Format(
                                    "{0}{1}{2}_index_{3}_sol_type_{4}_coords_{5}_number_{6}{7}",
                                    dir_diff,
                                    Path.DirectorySeparatorChar,
                                    Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file.FullName)),
                                    index,
                                    n.Solution.Type,
                                    number.Coords,
                                    number.Number,
                                    FileExtensions.XmlZipExt);

                                new SudokuIntermediateSolution(n.Parent.Board, n.Board,
                                                               n.Solution).SaveToFile(diff_file);

                                index++;
                            }
                        }
                    }
                }
            });

            Assert.IsTrue(ok);
        }
        public void Test_Examples_Solvable()
        {
            SudokuOptions.Current.ShowAllSolutions = false;
            SudokuOptions.Current.IncludeBoxes     = true;

            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            FileInfo[] files = new DirectoryInfo(Directories.Examples).GetFiles(FileExtensions.XmlZipMask);

            ConcurrentBag <string> unsolvable = new ConcurrentBag <string>();

            ConcurrentCounter counter = new ConcurrentCounter();

            Parallel.ForEach(files, (file) =>
            {
                SudokuBoard board = SudokuBoard.LoadFromFile(file.FullName);
                Assert.IsNotNull(board, file.FullName);

                counter.Increment();
                pi.AddLine((counter.Value * 100 / files.Length).ToString());

                for (int i = 0; i < 4; i++)
                {
                    SudokuSolutionNode root_node = SudokuSolutionNode.CreateRoot(board);
                    SudokuSolutionNode node      = root_node.Solve();

                    if (!node.Board.IsSolved)
                    {
                        unsolvable.Add("unsolvable; rotate_" + i + "; " + file.Name);
                    }

                    board = board.Rotate();
                }
            });

            if (unsolvable.Count > 0)
            {
                foreach (var file in unsolvable)
                {
                    TestContext.WriteLine(file);
                }

                Assert.Fail();
            }
        }
        public void Test_Examples_Unsolvable()
        {
            SudokuOptions.Current.ShowAllSolutions = false;
            SudokuOptions.Current.IncludeBoxes     = true;

            FileInfo[] files = new DirectoryInfo(Directories.Examples +
                                                 Path.DirectorySeparatorChar + "Unsolvable").GetFiles(FileExtensions.XmlZipMask);

            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            ConcurrentBag <string> solvable = new ConcurrentBag <string>();

            ConcurrentCounter counter = new ConcurrentCounter();

            Parallel.ForEach(files, (file) =>
            {
                counter.Increment();
                pi.AddLine((counter.Value * 100 / files.Length).ToString());

                SudokuBoard board = SudokuBoard.LoadFromFile(file.FullName);
                Assert.IsNotNull(board, file.FullName);

                SudokuSolutionNode root_node = SudokuSolutionNode.CreateRoot(board);
                SudokuSolutionNode node      = root_node.Solve();

                if (node.Board.IsSolved)
                {
                    solvable.Add("solvable; " + file.FullName);
                }
            });

            if (solvable.Count != 0)
            {
                foreach (var line in solvable)
                {
                    TestContext.WriteLine(line);
                }

                Assert.Fail();
            }
        }
Beispiel #5
0
        protected void TestExtremelyLong()
        {
            const int   SLEEP_TIME_MS   = 10;
            int         THREADS         = System.Environment.ProcessorCount;
            const float TARGET_CPU_LOAD = 0.4f;

            Assert.IsTrue(THREADS <= System.Environment.ProcessorCount);

            ProgressIndicator pi = new ProgressIndicator("Crypto +4GB Test");

            pi.AddLine(String.Format("Configuration: {0} threads, CPU Load: {1}%", THREADS, TARGET_CPU_LOAD * 100));

            CancellationTokenSource src = new CancellationTokenSource();

            Task regulator = Task.Factory.StartNew(token =>
            {
                PerformanceCounter pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");

                List <float> cpu_load = new List <float>();

                for (;;)
                {
                    const int PROBE_DELTA_MS = 200;
                    const int PROBE_COUNT    = 30;
                    const int REGULATE_COUNT = 10;

                    for (int i = 0; i < REGULATE_COUNT; i++)
                    {
                        System.Threading.Thread.Sleep(PROBE_DELTA_MS);

                        cpu_load.Add(pc.NextValue() / 100);

                        if (src.IsCancellationRequested)
                        {
                            break;
                        }
                    }

                    while (cpu_load.Count > PROBE_COUNT)
                    {
                        cpu_load.RemoveFirst();
                    }

                    int old_transform_rounds = transform_rounds;

                    float avg_cpu_load = cpu_load.Average();

                    if (avg_cpu_load >= TARGET_CPU_LOAD)
                    {
                        transform_rounds = (int)Math.Round(transform_rounds * 0.9);

                        if (old_transform_rounds == transform_rounds)
                        {
                            transform_rounds--;
                        }
                    }
                    else
                    {
                        transform_rounds = (int)Math.Round(transform_rounds * 1.1);

                        if (old_transform_rounds == transform_rounds)
                        {
                            transform_rounds++;
                        }
                    }

                    if (transform_rounds == 0)
                    {
                        transform_rounds = 1;
                    }

                    if (src.IsCancellationRequested)
                    {
                        break;
                    }
                }
            }, src.Token);

            var partitioner = Partitioner.Create(Hashes.CryptoAll, EnumerablePartitionerOptions.None);

            Parallel.ForEach(partitioner, new ParallelOptions()
            {
                MaxDegreeOfParallelism = THREADS
            }, ht =>
            {
                IHash hash = (IHash)Activator.CreateInstance(ht);

                pi.AddLine(String.Format("{0} / {1} - {2} - {3}%", Hashes.CryptoAll.IndexOf(ht) + 1,
                                         Hashes.CryptoAll.Count, hash.Name, 0));

                TestData test_data = TestData.Load(hash);

                int test_data_index = 0;

                for (int i = 0; i < test_data.Count; i++)
                {
                    if (test_data.GetRepeat(i) == 1)
                    {
                        continue;
                    }

                    test_data_index++;

                    ulong repeats          = (ulong)test_data.GetRepeat(i);
                    byte[] data            = test_data.GetData(i);
                    string expected_result = Converters.ConvertBytesToHexString(test_data.GetHash(i));

                    hash.Initialize();

                    int transform_counter = transform_rounds;
                    DateTime progress     = DateTime.Now;

                    for (ulong j = 0; j < repeats; j++)
                    {
                        hash.TransformBytes(data);

                        transform_counter--;
                        if (transform_counter == 0)
                        {
                            System.Threading.Thread.Sleep(SLEEP_TIME_MS);
                            transform_counter = transform_rounds;
                        }

                        if (DateTime.Now - progress > TimeSpan.FromSeconds(5))
                        {
                            pi.AddLine(String.Format("{0} / {1} / {2} - {3} - {4}%", Hashes.CryptoAll.IndexOf(ht) + 1,
                                                     test_data_index, Hashes.CryptoAll.Count, hash.Name, j * 100 / repeats));
                            progress = DateTime.Now;
                        }
                    }

                    HashResult result = hash.TransformFinal();

                    Assert.AreEqual(expected_result, Converters.ConvertBytesToHexString(result.GetBytes()), hash.ToString());

                    pi.AddLine(String.Format("{0} / {1} / {2} - {3} - {4}", Hashes.CryptoAll.IndexOf(ht) + 1,
                                             test_data_index, Hashes.CryptoAll.Count, hash.Name, "OK"));
                }
            });

            src.Cancel();
            regulator.Wait();
        }
Beispiel #6
0
        protected void TestExtremelyLong()
        {
            const int SLEEP_TIME_MS = 10;
            int THREADS = System.Environment.ProcessorCount;
            const float TARGET_CPU_LOAD = 0.4f;

            Assert.IsTrue(THREADS <= System.Environment.ProcessorCount);

            ProgressIndicator pi = new ProgressIndicator("Crypto +4GB Test");

            pi.AddLine(String.Format("Configuration: {0} threads, CPU Load: {1}%", THREADS, TARGET_CPU_LOAD * 100));

            CancellationTokenSource src = new CancellationTokenSource();

            Task regulator = Task.Factory.StartNew(token =>
            {
                PerformanceCounter pc = new PerformanceCounter("Processor", "% Processor Time", "_Total");

                List<float> cpu_load = new List<float>();

                for (;;)
                {
                    const int PROBE_DELTA_MS = 200;
                    const int PROBE_COUNT = 30;
                    const int REGULATE_COUNT = 10;

                    for (int i = 0; i < REGULATE_COUNT; i++)
                    {
                        System.Threading.Thread.Sleep(PROBE_DELTA_MS);

                        cpu_load.Add(pc.NextValue() / 100);

                        if (src.IsCancellationRequested)
                            break;
                    }

                    while (cpu_load.Count > PROBE_COUNT)
                        cpu_load.RemoveFirst();

                    int old_transform_rounds = transform_rounds;

                    float avg_cpu_load = cpu_load.Average();

                    if (avg_cpu_load >= TARGET_CPU_LOAD)
                    {
                        transform_rounds = (int)Math.Round(transform_rounds * 0.9);

                        if (old_transform_rounds == transform_rounds)
                            transform_rounds--;
                    }
                    else
                    {
                        transform_rounds = (int)Math.Round(transform_rounds * 1.1);

                        if (old_transform_rounds == transform_rounds)
                            transform_rounds++;
                    }

                    if (transform_rounds == 0)
                        transform_rounds = 1;

                    if (src.IsCancellationRequested)
                        break;
                }
            }, src.Token);

            var partitioner = Partitioner.Create(Hashes.CryptoAll, EnumerablePartitionerOptions.None);

            Parallel.ForEach(partitioner, new ParallelOptions() { MaxDegreeOfParallelism = THREADS }, ht =>
            {
                IHash hash = (IHash)Activator.CreateInstance(ht);

                pi.AddLine(String.Format("{0} / {1} - {2} - {3}%", Hashes.CryptoAll.IndexOf(ht) + 1,
                    Hashes.CryptoAll.Count, hash.Name, 0));

                TestData test_data = TestData.Load(hash);

                int test_data_index = 0;

                for (int i = 0; i < test_data.Count; i++)
                {
                    if (test_data.GetRepeat(i) == 1)
                        continue;

                    test_data_index++;

                    ulong repeats = (ulong)test_data.GetRepeat(i);
                    byte[] data = test_data.GetData(i);
                    string expected_result = Converters.ConvertBytesToHexString(test_data.GetHash(i));

                    hash.Initialize();

                    int transform_counter = transform_rounds;
                    DateTime progress = DateTime.Now;

                    for (ulong j = 0; j < repeats; j++)
                    {
                        hash.TransformBytes(data);

                        transform_counter--;
                        if (transform_counter == 0)
                        {
                            System.Threading.Thread.Sleep(SLEEP_TIME_MS);
                            transform_counter = transform_rounds;
                        }

                        if (DateTime.Now - progress > TimeSpan.FromSeconds(5))
                        {
                            pi.AddLine(String.Format("{0} / {1} / {2} - {3} - {4}%", Hashes.CryptoAll.IndexOf(ht) + 1,
                                test_data_index, Hashes.CryptoAll.Count, hash.Name, j * 100 / repeats));
                            progress = DateTime.Now;
                        }
                    }

                    HashResult result = hash.TransformFinal();

                    Assert.AreEqual(expected_result, Converters.ConvertBytesToHexString(result.GetBytes()), hash.ToString());

                    pi.AddLine(String.Format("{0} / {1} / {2} - {3} - {4}", Hashes.CryptoAll.IndexOf(ht) + 1,
                        test_data_index, Hashes.CryptoAll.Count, hash.Name, "OK"));
                }
            });

            src.Cancel();
            regulator.Wait();
        }
        public void Test_Solution_Trees_Consolidate()
        {
            SudokuOptions.Current.ShowAllSolutions = false;

            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            FileInfo[] files = new DirectoryInfo(Directories.SolutionTrees).GetFiles(FileExtensions.XmlZipMask);

            string dir = Directories.SolutionTrees + Path.DirectorySeparatorChar + "Consolidate";

            new DirectoryInfo(dir).CreateOrEmpty();

            int index = 0;
            ConcurrentCounter counter = new ConcurrentCounter();

            Parallel.ForEach(files, (file) =>
            {
                counter.Increment();
                pi.AddLine((counter.Value * 100 / files.Length).ToString());

                SudokuSolutionNode root = SudokuSolutionNode.LoadFromFile(file.FullName);

                foreach (SudokuSolutionNode node in root.GetAllNodesEnumerator())
                {
                    if (node.State != SudokuSolutionNodeState.State)
                    {
                        continue;
                    }

                    var filtered_sols = SudokuSolutionNode.FilterByOptions(node.Nodes.Select(n => n.Solution).ToList());

                    var filtered_nodes = (from n in node.Nodes
                                          where filtered_sols.Contains(n.Solution)
                                          select n).ToList();

                    var new_includes = (from n1 in filtered_nodes
                                        from n2 in filtered_nodes
                                        where SudokuSolutionNode.IsInclude(n1.Solution, n2.Solution, false)
                                        select new { n1, n2 }).ToList();

                    var ignore_pairs = new[]
                    {
                        new [] { SudokuSolutionType.NakedPair, SudokuSolutionType.BoxLineReduction },
                        new [] { SudokuSolutionType.NakedPair, SudokuSolutionType.PointingPair },
                        new [] { SudokuSolutionType.NakedPair, SudokuSolutionType.NakedTriple },
                        new [] { SudokuSolutionType.NakedPair, SudokuSolutionType.NakedQuad },
                        new [] { SudokuSolutionType.NakedTriple, SudokuSolutionType.BoxLineReduction },
                        new [] { SudokuSolutionType.NakedTriple, SudokuSolutionType.NakedQuad },
                        new [] { SudokuSolutionType.NakedTriple, SudokuSolutionType.PointingPair },
                        new [] { SudokuSolutionType.NakedTriple, SudokuSolutionType.PointingTriple },
                        new [] { SudokuSolutionType.NakedQuad, SudokuSolutionType.PointingPair },
                        new [] { SudokuSolutionType.HiddenPair, SudokuSolutionType.HiddenTriple },
                        new [] { SudokuSolutionType.HiddenPair, SudokuSolutionType.HiddenQuad },
                        new [] { SudokuSolutionType.HiddenTriple, SudokuSolutionType.HiddenQuad },
                    };

                    var ignore = from pair in new_includes
                                 from ignore_pair in ignore_pairs
                                 where (((pair.n1.Solution.Type == ignore_pair.First()) &&
                                         (pair.n2.Solution.Type == ignore_pair.Last())) ||
                                        ((pair.n1.Solution.Type == ignore_pair.Last()) &&
                                         (pair.n2.Solution.Type == ignore_pair.First())))
                                 select pair;

                    new_includes = new_includes.Except(ignore).ToList();

                    var doubles = from p1 in new_includes
                                  from p2 in new_includes
                                  where (p1.n1 == p2.n2) &&
                                  (p1.n2 == p2.n1)
                                  select p1;

                    new_includes = new_includes.Except(doubles).ToList();

                    foreach (var pair in new_includes)
                    {
                        SudokuIntermediateSolution intermediate_solution_1 =
                            new SudokuIntermediateSolution(pair.n1.Board, pair.n1.NextBoard, pair.n1.Solution);

                        intermediate_solution_1.SaveToFile(dir + Path.DirectorySeparatorChar + index + "_" +
                                                           Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file.FullName)) + "_" +
                                                           pair.n1.Solution.Type + FileExtensions.XmlZipExt);

                        SudokuIntermediateSolution intermediate_solution_2 =
                            new SudokuIntermediateSolution(pair.n2.Board, pair.n2.NextBoard, pair.n2.Solution);

                        intermediate_solution_2.SaveToFile(dir + Path.DirectorySeparatorChar + index + "_" +
                                                           Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(file.FullName)) + "_" +
                                                           pair.n2.Solution.Type + FileExtensions.XmlZipExt);

                        index++;
                    }
                }
            });

            Assert.IsTrue(index == 0);
        }
        public void Test_Solution_Trees_vs_Examples()
        {
            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            FileInfo[] files1 = new DirectoryInfo(Directories.Examples).GetFiles(FileExtensions.XmlZipMask);
            FileInfo[] files2 = new DirectoryInfo(Directories.SolutionTrees).GetFiles(FileExtensions.XmlZipMask);

            var not_all = (from file1 in files1
                           where files2.Count(fi => Directories.ConvertName(fi.FullName) == file1.Name) < 4
                           select file1).ToArray();

            var too_much = (from file2 in files2
                            where files1.All(fi => fi.Name != Directories.ConvertName(file2.Name))
                            select file2).ToArray();

            if (not_all.Count() > 0)
            {
                Assert.Fail("Is in 'Examples', but not in 'SolutionTrees' (run project 'SudokuGenerator'): " +
                            not_all.First().FullName);
            }

            if (too_much.Count() > 0)
            {
                Assert.Fail("Is in 'SolutionTrees', but not in 'Examples': " + too_much.First().FullName);
            }

            string dir3 = Directories.SolutionTrees + Path.DirectorySeparatorChar + "Diffrencies";

            new DirectoryInfo(dir3).CreateOrEmpty();

            string dir4 = Directories.SolutionTrees + Path.DirectorySeparatorChar + "Diffrencies" +
                          Path.DirectorySeparatorChar + "Added";

            new DirectoryInfo(dir4).CreateOrEmpty();

            string dir5 = Directories.SolutionTrees + Path.DirectorySeparatorChar + "Diffrencies" +
                          Path.DirectorySeparatorChar + "Removed";

            new DirectoryInfo(dir5).CreateOrEmpty();

            bool b = false;

            ConcurrentBag <string> list = new ConcurrentBag <string>();

            ConcurrentCounter counter = new ConcurrentCounter();

            Parallel.ForEach(files2, (file2, state) =>
            {
                counter.Increment();
                pi.AddLine((counter.Value * 100 / files2.Length).ToString());

                SudokuSolutionNode node2 = SudokuSolutionNode.LoadFromFile(file2.FullName);

                SudokuBoard board = SudokuBoard.LoadFromFile(files1.First(f => f.Name ==
                                                                          Directories.ConvertName(file2.FullName)).FullName);

                board = board.Rotate(ExtractRotateNumber(file2.Name));

                SudokuSolutionNode node1 = SudokuSolutionNode.CreateRoot(board);
                node1.SolveWithStepAll();

                Assert.AreEqual(node1.State, node2.State, file2.FullName);
                Assert.AreEqual(node1.Board, node2.Board, file2.FullName);
                Assert.AreEqual(node1.Solution, node2.Solution, file2.FullName);

                b |= CompareNodes(node1, node2, file2, list, 1, 1);
            });

            if (list.Count != 0)
            {
                string filename = dir3 + Path.DirectorySeparatorChar + "!Diffrencies.txt";

                using (FileStream fs = new FileStream(filename, FileMode.Create))
                {
                    StreamWriter sw = new StreamWriter(fs);
                    list.ForEach(s => sw.WriteLine(s));
                    sw.Flush();
                }

                TestContext.AddResultFile(filename);
            }

            Assert.IsFalse(b);
        }
        public void Test_Solutions_Unique()
        {
            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            FileInfo[] files = new DirectoryInfo(Directories.Solutions).GetFiles(FileExtensions.XmlZipMask);

            var solutions1 = (from file in files.AsParallel()
                              select new
            {
                intermediate_solution = SudokuIntermediateSolution.LoadFromFile(file.FullName),
                fileName = file.FullName,
            }).ToArray();

            solutions1.ForEach(example => Assert.IsNotNull(example.intermediate_solution, example.fileName));

            var solutions2 = (from sol in solutions1.AsParallel()
                              select new[]
            {
                new
                {
                    intermediate_solution = sol.intermediate_solution,
                    fileName = sol.fileName,
                    rotate = 0
                },
                new
                {
                    intermediate_solution = sol.intermediate_solution.Rotate(),
                    fileName = sol.fileName,
                    rotate = 1
                },
                new
                {
                    intermediate_solution = sol.intermediate_solution.Rotate().Rotate(),
                    fileName = sol.fileName,
                    rotate = 2
                },
                new
                {
                    intermediate_solution = sol.intermediate_solution.Rotate().Rotate().Rotate(),
                    fileName = sol.fileName,
                    rotate = 3
                }
            }).SelectMany().ToArray();

            var solutions_gr = (from obj in solutions2
                                group obj by obj.intermediate_solution.Solution.Type into gr
                                select(from obj in gr
                                       orderby obj.fileName
                                       select obj).ToArray()).ToArray();

            solutions_gr = (from gr in solutions_gr
                            select(gr.Length == 80) ? new[] { gr.Take(40).ToArray(), gr.Skip(40).Take(40).ToArray() } :
                            new[] { gr }).SelectMany(gr => gr.ToArray()).ToArray();

            ConcurrentBag <string> not_uniques = new ConcurrentBag <string>();

            ConcurrentCounter counter = new ConcurrentCounter();
            int count = solutions_gr.Sum(gr => gr.Length);

            Parallel.ForEach(solutions_gr, (solution_gr) =>
            {
                var sols = solution_gr;

                foreach (var solution1 in sols)
                {
                    foreach (var solution2 in sols.Except(solution1))
                    {
                        if (sols.IndexOf(solution1) >= sols.IndexOf(solution2))
                        {
                            continue;
                        }
                        if ((solution1.fileName == solution2.fileName))
                        {
                            continue;
                        }

                        if (solution1.intermediate_solution.Equals(solution2.intermediate_solution))
                        {
                            not_uniques.Add("are the same");
                            not_uniques.Add("solution1; " + solution1.rotate + " - " + solution1.fileName);
                            not_uniques.Add("solution2; " + solution2.rotate + " - " + solution2.fileName);
                        }
                    }

                    counter.Increment();
                    pi.AddLine((counter.Value * 100 / count).ToString());
                }
            });

            if (not_uniques.Count != 0)
            {
                foreach (var line in not_uniques)
                {
                    TestContext.WriteLine(line);
                }

                Assert.Fail();
            }
        }
        public void Test_Solutions_Solvable()
        {
            SudokuOptions.Current.ShowAllSolutions = false;
            SudokuOptions.Current.IncludeBoxes     = true;

            FileInfo[] files = new DirectoryInfo(Directories.Solutions).GetFiles(FileExtensions.XmlZipMask);

            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var solutions1 = (from file in files.AsParallel()
                              select new
            {
                intermediate_solution = SudokuIntermediateSolution.LoadFromFile(file.FullName),
                fileName = file.FullName
            }).ToArray();

            var solutions2 = (from sol in solutions1.AsParallel()
                              select new[]
            {
                new
                {
                    intermediate_solution = sol.intermediate_solution,
                    fileName = sol.fileName,
                    rotate = 0
                },
                new
                {
                    intermediate_solution = sol.intermediate_solution.Rotate(),
                    fileName = sol.fileName,
                    rotate = 1
                },
                new
                {
                    intermediate_solution = sol.intermediate_solution.Rotate().Rotate(),
                    fileName = sol.fileName,
                    rotate = 2
                },
                new
                {
                    intermediate_solution = sol.intermediate_solution.Rotate().Rotate().Rotate(),
                    fileName = sol.fileName,
                    rotate = 3
                }
            }).SelectMany().ToArray();

            var solutions3 = (from sol in solutions2
                              group sol by sol.intermediate_solution.Solution.Type into gr
                              select gr.ToArray()).ToArray();

            ConcurrentBag <string> unsolvable = new ConcurrentBag <string>();

            int count = solutions3.Sum(gr => gr.Count());
            ConcurrentCounter counter = new ConcurrentCounter();

            Parallel.ForEach(ChunkPartitioner.Create(solutions3.SelectMany(), 10), (solution) =>
            {
                if (!solution.intermediate_solution.Test(true))
                {
                    unsolvable.Add("unsolvable; rotate_" + solution.rotate + "; " + solution.fileName);
                }

                counter.Increment();

                pi.AddLine((counter.Value * 100 / count).ToString());
            });

            if (unsolvable.Count > 0)
            {
                foreach (var file in unsolvable)
                {
                    TestContext.WriteLine(file);
                }

                Assert.Fail();
            }
        }
        public void Test_Examples_Unique()
        {
            FileInfo[] files1 = new DirectoryInfo(Directories.Examples).GetFiles(FileExtensions.XmlZipMask);
            FileInfo[] files2 = new DirectoryInfo(Directories.Examples + Path.DirectorySeparatorChar +
                                                  "Unsolvable").GetFiles(FileExtensions.XmlZipMask);

            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var examples1 = from file in files1.Concat(files2).AsParallel()
                            select new
            {
                board    = SudokuBoard.LoadFromFile(file.FullName),
                fileName = file.FullName
            };

            var examples2 = (from example in examples1.AsParallel()
                             select new[]
            {
                new
                {
                    board = example.board,
                    fileName = example.fileName,
                    rotate = 0
                },
                new
                {
                    board = example.board.Rotate(),
                    fileName = example.fileName,
                    rotate = 1
                },
                new
                {
                    board = example.board.Rotate().Rotate(),
                    fileName = example.fileName,
                    rotate = 2
                },
                new
                {
                    board = example.board.Rotate().Rotate().Rotate(),
                    fileName = example.fileName,
                    rotate = 3
                }
            }).SelectMany().ToArray();

            ConcurrentBag <string> not_uniques = new ConcurrentBag <string>();

            ConcurrentCounter counter = new ConcurrentCounter();

            Parallel.ForEach(examples2, (example1) =>
            {
                counter.Increment();
                pi.AddLine((counter.Value * 100 / examples2.Length).ToString());

                foreach (var example2 in examples2.Except(example1))
                {
                    if (example1.fileName == example2.fileName)
                    {
                        continue;
                    }

                    if ((from num1 in example1.board.Numbers()
                         where num1.IsSolved
                         select num1).All(num1 => example2.board[num1.Col, num1.Row][num1.Number - 1].IsSolved))
                    {
                        not_uniques.Add("not unique");
                        not_uniques.Add("example; rotate_" + example1.rotate + "; " + example1.fileName);
                        not_uniques.Add("include in rotate_" + example2.rotate + "; " + example2.fileName);
                    }
                }
            });

            if (not_uniques.Count != 0)
            {
                foreach (var line in not_uniques)
                {
                    TestContext.WriteLine(line);
                }

                Assert.Fail();
            }
        }
        public void Test_Solutions_Quantity()
        {
            SudokuOptions.Current.ShowAllSolutions = false;
            SudokuOptions.Current.IncludeBoxes     = true;

            ProgressIndicator pi = new ProgressIndicator(System.Reflection.MethodBase.GetCurrentMethod().Name);

            FileInfo[] files = new DirectoryInfo(Directories.Solutions).GetFiles(FileExtensions.XmlZipMask);

            var solutions = (from file in files.AsParallel()
                             select new
            {
                intermediate_solution = SudokuIntermediateSolution.LoadFromFile(file.FullName),
                fileName = file.FullName,
            }).ToArray();

            solutions.ForEach(example => Assert.IsNotNull(example.intermediate_solution, example.fileName));

            var solutions_gr = (from obj in solutions
                                group obj by obj.intermediate_solution.Solution.Type into gr
                                select(from obj in gr
                                       orderby obj.fileName
                                       select obj).ToArray()).ToArray();

            ConcurrentBag <string> bad_quantities = new ConcurrentBag <string>();

            Parallel.ForEach(solutions_gr, (solution_gr) =>
            {
                pi.AddLine((solutions_gr.IndexOf(solution_gr) * 100 / solutions_gr.Count()).ToString());

                if (new[] { SudokuSolutionType.XWing, SudokuSolutionType.JellyFish,
                            SudokuSolutionType.SwordFish }.Contains(
                        solution_gr.First().intermediate_solution.Solution.Type))
                {
                    if (solution_gr.Count() < 20)
                    {
                        bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type + " - less then 20");
                    }
                    else if (solution_gr.Count() > 20)
                    {
                        bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type + " - more then 20");
                    }
                    else
                    {
                        SudokuOptions.Current.IncludeBoxes = false;

                        var gr1 = (from obj in solution_gr.Take(10)
                                   select obj.intermediate_solution.Solution).ToList();
                        int c1 = SudokuSolutionNode.FilterByOptions(gr1).Count();
                        if (c1 == 0)
                        {
                            bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type +
                                               " - solutions from 1 to 10 doesn't contains any boxes");
                        }
                        if (c1 == 10)
                        {
                            bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type +
                                               " - solutions from 1 to 10 all contains boxes");
                        }

                        SudokuOptions.Current.IncludeBoxes = false;
                        var gr2 = (from obj in solution_gr.Skip(10).Take(10)
                                   select obj.intermediate_solution.Solution).ToList();
                        int c2 = SudokuSolutionNode.FilterByOptions(gr2).Count();
                        if (c2 != 10)
                        {
                            bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type +
                                               " - solutions from 11 to 20 some contains boxes");
                        }
                    }
                }
                else
                {
                    if (solution_gr.Count() < 10)
                    {
                        bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type + " - less then 10");
                    }
                    if (solution_gr.Count() > 10)
                    {
                        bad_quantities.Add(solution_gr.First().intermediate_solution.Solution.Type + " - more then 10");
                    }
                }
            });

            if (solutions_gr.Count() != Enum.GetValues(typeof(SudokuSolutionType)).Length)
            {
                bad_quantities.Add("Not all algorithms was tested");
            }

            if (bad_quantities.Count != 0)
            {
                foreach (var line in bad_quantities)
                {
                    TestContext.WriteLine(line);
                }
            }
        }