Example #1
0
        protected Sudoku.Core.Sudoku SolveOriginalCleanup(Sudoku.Core.Sudoku instance)
        {
            BoolExpr instance_c = GetPuzzleConstraint(instance);
            var      z3Solver   = GetSolver();

            z3Solver.Assert(GenericContraints);
            z3Solver.Assert(instance_c);

            if (z3Solver.Check() == Status.SATISFIABLE)
            {
                Model m = z3Solver.Model;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        if (instance.GetCell(i, j) == 0)
                        {
                            instance.SetCell(i, j, ((IntNum)m.Evaluate(X[i][j])).Int);
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("Failed to solve sudoku");
            }
            return(instance);
        }
Example #2
0
        private static Sudoku.Core.Sudoku SolutionToSudoku(
            IReadOnlyList <Tuple <int, int, int, bool> > internalRows,
            Solution solution, Sudoku.Core.Sudoku sudoku)
        {
            List <int> mySudoku = new List <int>();

            Sudoku.Core.Sudoku mySudokuSolution = new Sudoku.Core.Sudoku();
            var rowStrings = solution.RowIndexes
                             .Select(rowIndex => internalRows[rowIndex])
                             .OrderBy(t => t.Item1)
                             .ThenBy(t => t.Item2)
                             .GroupBy(t => t.Item1, t => t.Item3)
                             .Select(value => string.Concat(value))
                             .ToImmutableList();

            mySudokuSolution.Cells.Clear();
            for (int i = 0; i < rowStrings.Count; i++)
            {
                string line = rowStrings[i].Replace(" ", "0");
                foreach (char myChar in line)
                {
                    mySudokuSolution.Cells.Add(int.Parse(myChar.ToString()));
                }
            }
            return(mySudokuSolution);
        }
Example #3
0
        public Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku s)
        {
            var strGrid = new List <string>(9);

            for (int i = 0; i < 9; i++)
            {
                var i1 = i;
                strGrid.Add(string.Join("", Indices.Select(j => s.Cells[i1 * 9 + j]).Select(i2 => i2 == 0 ? " " : i2.ToString(CultureInfo.InvariantCulture))));
            }
            var grid = new Grid(ImmutableList.Create(strGrid.ToArray()));

            /*int[,] mySudoku = new int[9, 9];
             * for (int i = 0; i < 9; i++) {
             *  for (int j = 0; j < 9; j++) {
             *      mySudoku[i, j] = mySudoku[i, s.Cells[j]];
             *  }
             * }
             */
            //var internalRows = BuildInternalRowsForSudoku(mySudoku);
            var internalRows = BuildInternalRowsForSudoku(grid);
            var dlxRows      = BuildDlxRows(internalRows);
            var solutions    = new Dlx()
                               .Solve(dlxRows, d => d, r => r)
                               .Where(solution => VerifySolution(internalRows, solution))
                               .ToImmutableList();

            //return SolutionToGrid(internalRows, solutions.First());
            return(SolutionToSudoku(internalRows, solutions.First(), s));
        }
Example #4
0
        protected Sudoku.Core.Sudoku SolveWithScope(Sudoku.Core.Sudoku instance)
        {
            var z3Solver = GetReusableSolver();

            z3Solver.Push();
            BoolExpr instance_c = GetPuzzleConstraint(instance);

            z3Solver.Assert(instance_c);

            if (z3Solver.Check() == Status.SATISFIABLE)
            {
                Model m = z3Solver.Model;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        if (instance.GetCell(i, j) == 0)
                        {
                            instance.SetCell(i, j, ((IntNum)m.Evaluate(X[i][j])).Int);
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("Failed to solve sudoku");
            }
            z3Solver.Pop();
            return(instance);
        }
        public Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku s)
        {
            int[,] instance = new int[9, 9];

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    instance[i, j] = s.GetCell(i, j);
                }
            }

            IntExpr[,] R = SudokuExample(instance);

            var listCells = new List <int>(81);

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    listCells.Add(((IntNum)R[i, j]).Int);
                }
            }
            return(new Sudoku.Core.Sudoku(listCells));
        }
Example #6
0
        public Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku grid_sudoku)
        {
            var solution = search(parse_grid(grid_sudoku));

            Sudoku.Core.Sudoku solution_sudoku = Sudoku.Core.Sudoku.Parse(toLine(solution));

            return(solution_sudoku);
        }
Example #7
0
        static void DisplayEasy()
        {
            var allSudokus = LoadEasy();

            for (int i = 0; i < allSudokus.Count; i++)
            {
                Sudoku.Core.Sudoku sudoku = (Sudoku.Core.Sudoku)allSudokus[i];
                Console.WriteLine(sudoku.ToString());
            }
        }
Example #8
0
        public Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku s)
        {
            using (var ctx = new Z3Context())
            {
                var theorem = CreateTheorem(ctx, s);

                theorem.DefaultCollectionHandling = CollectionHandling.Constants;

                return(theorem.Solve());
            }
        }
Example #9
0
        static void Benchmark1()
        {
            var solvers = new List <ISudokuSolver>();



            foreach (var file in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory))
            {
                if (file.EndsWith("dll") && !(Path.GetFileName(file).StartsWith("libz3")))
                {
                    var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
                    foreach (var type in assembly.GetTypes())
                    {
                        if (typeof(ISudokuSolver).IsAssignableFrom(type) && !(typeof(ISudokuSolver) == type))
                        {
                            var solver = (ISudokuSolver)Activator.CreateInstance(type);
                            solvers.Add(solver);
                        }
                    }
                }
            }

            var allSudokus    = LoadEasy();
            var premierSudoku = allSudokus[0];

            Console.WriteLine(premierSudoku.ToString());
            TimeSpan tempsTotal = new TimeSpan();

            var chrono = new Stopwatch();

            foreach (var sudokuSolver in solvers)
            {
                foreach (var unsudoku in allSudokus)
                {
                    var aResoudre = new Sudoku.Core.Sudoku()
                    {
                        Cells = new List <int>(unsudoku.Cells)
                    };
                    chrono.Restart();
                    var resolu     = sudokuSolver.Solve(aResoudre);
                    var tempsPasse = chrono.Elapsed;
                    tempsTotal += tempsPasse;
                    Console.WriteLine(sudokuSolver.GetType().Name);
                    Console.WriteLine(resolu.ToString());
                    Console.WriteLine(tempsPasse.ToString());
                }
                Console.WriteLine(String.Concat("temps total de résolution pour ", sudokuSolver.GetType().Name, " :", tempsTotal.ToString()));
            }
        }
Example #10
0
        BoolExpr GetPuzzleConstraint(Sudoku.Core.Sudoku instance)
        {
            BoolExpr instance_c = z3Context.MkTrue();

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (instance.GetCell(i, j) != 0)
                    {
                        instance_c = z3Context.MkAnd(instance_c,
                                                     (BoolExpr)
                                                     z3Context.MkEq(X[i][j], z3Context.MkInt(instance.GetCell(i, j))));
                    }
                }
            }
            return(instance_c);
        }
Example #11
0
        public static Dictionary <string, string> parse_grid(Sudoku.Core.Sudoku grid_sudoku)
        {
            string grid = toLine(grid_sudoku);

            var values = squares.ToDictionary(s => s, s => digits);

            foreach (var sd in zip(squares, (from s in grid select s.ToString()).ToArray()))
            {
                var s = sd[0];
                var d = sd[1];

                if (digits.Contains(d) && assign(values, s, d) == null)
                {
                    return(null);
                }
            }
            return(values);
        }
Example #12
0
        protected Sudoku.Core.Sudoku SolveWithSubstitutions(Sudoku.Core.Sudoku instance)
        {
            var substExprs = new List <Expr>();
            var substVals  = new List <Expr>();

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (instance.GetCell(i, j) != 0)
                    {
                        substExprs.Add(X[i][j]);
                        substVals.Add(z3Context.MkInt(instance.GetCell(i, j)));
                    }
                }
            }
            BoolExpr instance_c = (BoolExpr)GenericContraints.Substitute(substExprs.ToArray(), substVals.ToArray());

            var z3Solver = GetSolver();

            z3Solver.Assert(instance_c);

            if (z3Solver.Check() == Status.SATISFIABLE)
            {
                Model m = z3Solver.Model;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        if (instance.GetCell(i, j) == 0)
                        {
                            instance.SetCell(i, j, ((IntNum)m.Evaluate(X[i][j])).Int);
                        }
                    }
                }
            }
            else
            {
                Console.WriteLine("Failed to solve sudoku");
            }
            return(instance);
        }
Example #13
0
        protected Sudoku.Core.Sudoku SolveOriginalVersion(Sudoku.Core.Sudoku instance)
        {
            BoolExpr instance_c = z3Context.MkTrue();

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    instance_c = z3Context.MkAnd(instance_c,
                                                 (BoolExpr)
                                                 z3Context.MkITE(z3Context.MkEq(z3Context.MkInt(instance.GetCell(i, j)), z3Context.MkInt(0)),
                                                                 z3Context.MkTrue(),
                                                                 z3Context.MkEq(X[i][j], z3Context.MkInt(instance.GetCell(i, j)))));
                }
            }

            Solver s = z3Context.MkSolver();

            s.Assert(GenericContraints);
            s.Assert(instance_c);

            if (s.Check() == Status.SATISFIABLE)
            {
                Model m = s.Model;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        instance.SetCell(i, j, ((IntNum)m.Evaluate(X[i][j])).Int);
                    }
                }
                return(instance);
            }
            else
            {
                Console.WriteLine("Failed to solve sudoku");
                return(instance);
            }
        }
Example #14
0
        Sudoku.Core.Sudoku SudokuExample(Sudoku.Core.Sudoku instance)
        {
            BoolExpr instance_c = _ctx.MkTrue();

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    instance_c = _ctx.MkAnd(instance_c,
                                            (BoolExpr)
                                            _ctx.MkITE(_ctx.MkEq(_ctx.MkInt(instance.GetCell(i, j)), _ctx.MkInt(0)),
                                                       _ctx.MkTrue(),
                                                       _ctx.MkEq(X[i][j], _ctx.MkInt(instance.GetCell(i, j)))));
                }
            }

            Solver s = _ctx.MkSolver();

            s.Assert(sudoku_c);
            s.Assert(instance_c);

            if (s.Check() == Status.SATISFIABLE)
            {
                Model m = s.Model;
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        instance.SetCell(i, j, ((IntNum)m.Evaluate(X[i][j])).Int);
                    }
                }
                return(instance);
            }
            else
            {
                Console.WriteLine("Failed to solve sudoku");
                return(instance);
            }
        }
Example #15
0
 public virtual Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku s)
 {
     return(SolveWithSubstitutions(s));
 }
Example #16
0
 public static String toLine(Sudoku.Core.Sudoku grid)
 {
     return(string.Join("", grid.Cells.Select(x => x.ToString()).ToArray()));
 }
        public Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku sudoku)
        {
            //Sudoku -> Tableau
            int[,] sudokuInGrid = new int[9, 9];

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    sudokuInGrid[i, j] = sudoku.GetCell(i, j);
                }
            }

            Solver solver = new Solver("Sudoku");

            int cell_size          = 3;
            IEnumerable <int> CELL = Enumerable.Range(0, cell_size);
            int n = cell_size * cell_size;
            IEnumerable <int> RANGE = Enumerable.Range(0, n);

            //Création de la grille de solution
            IntVar[,] grid = solver.MakeIntVarMatrix(n, n, 1, 9, "grid");
            IntVar[] grid_flat = grid.Flatten();

            //Tableau -> Solver
            foreach (int i in RANGE)
            {
                foreach (int j in RANGE)
                {
                    if (sudokuInGrid[i, j] > 0)
                    {
                        solver.Add(grid[i, j] == sudokuInGrid[i, j]);
                    }
                }
            }

            //Un chiffre ne figure qu'une seule fois par ligne/colonne/cellule
            foreach (int i in RANGE)
            {
                // Lignes
                solver.Add((from j in RANGE
                            select grid[i, j]).ToArray().AllDifferent());

                // Colonnes
                solver.Add((from j in RANGE
                            select grid[j, i]).ToArray().AllDifferent());
            }

            //Cellules
            foreach (int i in CELL)
            {
                foreach (int j in CELL)
                {
                    solver.Add((from di in CELL
                                from dj in CELL
                                select grid[i * cell_size + di, j * cell_size + dj]
                                ).ToArray().AllDifferent());
                }
            }

            //Début de la résolution
            DecisionBuilder db = solver.MakePhase(grid_flat,
                                                  Solver.INT_VAR_SIMPLE,
                                                  Solver.INT_VALUE_SIMPLE);

            solver.NewSearch(db);

            // Solver -> Liste
            var gridToSudoku = new List <int>();

            while (solver.NextSolution())
            {
                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        gridToSudoku.Add((int)grid[i, j].Value());
                    }
                }
            }
            solver.EndSearch();

            //Liste -> Sudoku
            return(new Sudoku.Core.Sudoku(gridToSudoku));
        }
Example #18
0
 public Sudoku.Core.Sudoku Solve(Sudoku.Core.Sudoku s)
 {
     //   Z3Solver z3 = new Z3Solver();
     return(SudokuExample(s));
 }
Example #19
0
        static void Benchmark1()
        {
            var solvers = new List <ISudokuSolver>();

            foreach (var file in Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory))
            {
                if (file.EndsWith("dll") && !(Path.GetFileName(file).StartsWith("libz3")))
                {
                    var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
                    foreach (var type in assembly.GetTypes())
                    {
                        if (typeof(ISudokuSolver).IsAssignableFrom(type) && !(typeof(ISudokuSolver) == type))
                        {
                            var solver = (ISudokuSolver)Activator.CreateInstance(type);
                            solvers.Add(solver);
                        }
                    }
                }
            }

            var allSudokus    = Menu();
            var premierSudoku = allSudokus[0];

            //Console.WriteLine(premierSudoku.ToString());


            var chrono = new Stopwatch();
            //  List<List<TimeSpan>> tempsTotalParSolver = new List<List<TimeSpan>>();
            List <TempsParSudoku> listParSolver = new List <TempsParSudoku>();

            Int32 i           = 0;
            bool  printSudoku = true;

            foreach (var unsudoku in allSudokus)
            {
                printSudoku = true;
                foreach (var sudokuSolver in solvers)
                {
                    var aResoudre = new Sudoku.Core.Sudoku()
                    {
                        Cells = new List <int>(unsudoku.Cells)
                    };
                    chrono.Restart();
                    var resolu     = sudokuSolver.Solve(aResoudre);
                    var tempsPasse = chrono.Elapsed;
                    if (printSudoku)
                    {
                        printSudoku = false;
                        Console.WriteLine(resolu.ToString());
                    }
                    Console.WriteLine(String.Concat("Temps résolu par ", sudokuSolver.GetType().Name, " : ", tempsPasse.ToString()));


                    listParSolver.Add(new TempsParSudoku(sudokuSolver.GetType().Name, tempsPasse));
                }

                //Pour le solver CSP en IronPython
                chrono.Restart();
                CSP(i);
                var tempsPasseCSP = chrono.Elapsed;
                listParSolver.Add(new TempsParSudoku("CSP", tempsPasseCSP));
                Console.WriteLine(String.Concat("Temps résolu par CSP : ", tempsPasseCSP.ToString()));
                i++;
            }
            ILookup <String, TempsParSudoku> tempsPasseSurUnSudokuBySolver = listParSolver.ToLookup(o => o.NomSolver);

            foreach (var solver in tempsPasseSurUnSudokuBySolver)
            {
                TimeSpan tempsTotal = new TimeSpan();
                foreach (var time in solver)
                {
                    tempsTotal += time.TempsPasse;
                }
                Console.WriteLine("Solver {0} a tout résolu en {1}", solver.Key, tempsTotal);
            }
        }
Example #20
0
        /// <summary>
        /// Creates a Z3-capable theorem to solve a Sudoku
        /// </summary>
        /// <param name="context">The wrapping Z3 context used to interpret c# Lambda into Z3 constraints</param>
        /// <returns>A typed theorem to be further filtered with additional contraints</returns>
        public static Theorem <Sudoku.Core.Sudoku> CreateTheorem(Z3Context context, Sudoku.Core.Sudoku s)
        {
            var sudokuTheorem = context.NewTheorem <Sudoku.Core.Sudoku>();


            for (int i = 0; i < 81; i++)
            {
                if (s.Cells[i] != 0)
                {
                    var idx       = i;
                    var cellValue = s.Cells[i];
                    sudokuTheorem = sudokuTheorem.Where(sudoku => sudoku.Cells[idx] == cellValue);
                }
            }



            // Cells have values between 1 and 9
            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    //To avoid side effects with lambdas, we copy indices to local variables
                    var i1 = i;
                    var j1 = j;
                    sudokuTheorem = sudokuTheorem.Where(sudoku => (sudoku.Cells[i1 * 9 + j1] > 0 && sudoku.Cells[i1 * 9 + j1] < 10));
                }
            }

            // Rows must have distinct digits
            for (int r = 0; r < 9; r++)
            {
                //Again we avoid Lambda closure side effects
                var r1 = r;
                sudokuTheorem = sudokuTheorem.Where(t => Z3Methods.Distinct(Indices.Select(j => t.Cells[r1 * 9 + j]).ToArray()));
            }

            // Columns must have distinct digits
            for (int c = 0; c < 9; c++)
            {
                //Preventing closure side effects
                var c1 = c;
                sudokuTheorem = sudokuTheorem.Where(t => Z3Methods.Distinct(Indices.Select(i => t.Cells[i * 9 + c1]).ToArray()));
            }

            // Boxes must have distinct digits
            for (int b = 0; b < 9; b++)
            {
                //On évite les effets de bords par closure
                var b1 = b;
                // We retrieve to top left cell for all boxes, using integer division and remainders.
                var iStart     = b1 / 3;
                var jStart     = b1 % 3;
                var indexStart = iStart * 3 * 9 + jStart * 3;
                sudokuTheorem = sudokuTheorem.Where(t => Z3Methods.Distinct(new int[]
                {
                    t.Cells[indexStart],
                    t.Cells[indexStart + 1],
                    t.Cells[indexStart + 2],
                    t.Cells[indexStart + 9],
                    t.Cells[indexStart + 10],
                    t.Cells[indexStart + 11],
                    t.Cells[indexStart + 18],
                    t.Cells[indexStart + 19],
                    t.Cells[indexStart + 20],
                }
                                                                            )
                                                    );
            }

            return(sudokuTheorem);
        }
Example #21
0
 public bool IsValid(Sudoku originalPuzzle)
 {
     return(NbErrors(originalPuzzle) == 0);
 }