internal static void MapCsp(int[] domain, int mapSize, int regionCount,
                                    ISelectVariableHeuristic <Point, int> selectVariable,
                                    IOrderDomainHeuristic <Point, int> orderDomain,
                                    SolverType solverType,
                                    int?seed = null)
        {
            var colorMapCsp = new MapColoringCsp(mapSize)
            {
                RandomGenerator = seed is null ? new Random() : new Random((int)seed)
            };

            colorMapCsp.ResetRegions(regionCount, domain);

            var solver = solverType switch
            {
                SolverType.Ac3 => new ArcConsistencySolver <Point, int>(selectVariable, orderDomain),
                SolverType.Backtracking => new BacktrackingSolver <Point, int>(selectVariable, orderDomain),
                _ => (CspSolver <Point, int>) new ForwardCheckingSolver <Point, int>(selectVariable, orderDomain)
            };

            var benchResult = BenchmarkCsp.BenchmarkFirstOnly(solver, colorMapCsp);

            Console.WriteLine($"__________________________\n{solverType}");
            benchResult.Report();
            if (benchResult.FirstSolution is not null)
            {
                MapCspSerializer.SerializeResultsToJson(benchResult.FirstSolution, colorMapCsp);
                MapCspSerializer.GenerateImage();
            }

            benchResult = BenchmarkCsp.BenchmarkAll(solver, colorMapCsp);
            benchResult.Report();
        }
        internal static void EinsteinCsp(
            ISelectVariableHeuristic <EinsteinValue, House> selectVariable,
            IOrderDomainHeuristic <EinsteinValue, House> orderDomain,
            SolverType solverType, bool showResult = false)
        {
            var einstein = new EinsteinCsp();
            var solver   = solverType switch
            {
                SolverType.Ac3 => new ArcConsistencySolver <EinsteinValue, House>(selectVariable, orderDomain),
                SolverType.Backtracking => new BacktrackingSolver <EinsteinValue, House>(selectVariable, orderDomain),
                _ => (CspSolver <EinsteinValue, House>) new ForwardCheckingSolver <EinsteinValue, House>(selectVariable,
                                                                                                         orderDomain)
            };

            var benchResult = BenchmarkCsp.BenchmarkFirstOnly(solver, einstein);

            if (showResult)
            {
                foreach (var house in HouseExtension.Houses)
                {
                    Console.WriteLine("_____________________");
                    Console.WriteLine(house);
                    Console.WriteLine("_____________________");
                    foreach (var einsteinValue in benchResult.FirstSolution
                             .Where(r => r.Value == house)
                             .Select(r => r.Key))
                    {
                        Console.WriteLine(einsteinValue);
                    }

                    Console.WriteLine("\n\n");
                }
            }

            Console.WriteLine($"__________________________\n{solverType}");
            benchResult.Report();
            benchResult = BenchmarkCsp.BenchmarkAll(solver, einstein);
            benchResult.Report();
        }
    }