Пример #1
0
        public void SecondaryColumnsCanBeCoveredOnlyOnceLikePrimaryColumns()
        {
            // Arrange
            var matrix = new List <List <int> >
            {
                new List <int> {
                    1, 0, 0, 0, 1
                },                             // 0
                new List <int> {
                    0, 1, 1, 0, 0
                },                             // 1
                new List <int> {
                    1, 0, 0, 1, 0
                },                             // 2
                new List <int> {
                    0, 0, 1, 1, 0
                },                             // 3
                new List <int> {
                    0, 1, 0, 0, 1
                },                             // 4
                new List <int> {
                    0, 0, 1, 0, 1
                }                              // 5
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix, d => d, r => r, 4).ToList();

            // Assert
            Assert.That(solutions, Has.Count.EqualTo(1));
            Assert.That(solutions.Select(s => s.RowIndexes), Contains.Item(new[] { 1, 2 }));
        }
Пример #2
0
        public void SearchStepEventsHaveIncreasingIteration()
        {
            var matrix = new[, ]
            {
                { 0, 0, 1, 0, 1, 1, 0 },
                { 1, 0, 0, 1, 0, 0, 1 },
                { 0, 1, 1, 0, 0, 1, 0 },
                { 1, 0, 0, 1, 0, 0, 0 },
                { 0, 1, 0, 0, 0, 0, 1 },
                { 0, 0, 0, 1, 1, 0, 1 }
            };
            var dlx = new Dlx();
            var searchStepEventArgs = new List <SearchStepEventArgs>();

            dlx.SearchStep += (_, e) => searchStepEventArgs.Add(e);

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            dlx.Solve(matrix).First();

            Assert.That(searchStepEventArgs.Count, Is.GreaterThanOrEqualTo(5));
            foreach (var index in Enumerable.Range(0, 5))
            {
                Assert.That(searchStepEventArgs[index].Iteration, Is.EqualTo(index));
            }
        }
Пример #3
0
        private void SolvePuzzleInBackground()
        {
            var tetraSticks = Model.TetraSticks.All.Where(ts => ts.Tag != _tetraStickToOmit.Tag).ToImmutableList();
            var rows = RowBuilder.BuildRows(tetraSticks);
            var matrix = DlxMatrixBuilder.BuildDlxMatrix(tetraSticks, rows);
            var dlx = new Dlx(_cancellationToken);

            dlx.SearchStep += (_, searchStepEventArgs) =>
            {
                var placedTetraSticks = searchStepEventArgs.RowIndexes.Select(idx => rows[idx]).ToImmutableList();
                _synchronizationContext.Post(_onSearchStep, placedTetraSticks);
            };

            //var solutions = dlx.Solve(matrix, d => d, r => r, 75);

            //foreach (var solution in solutions)
            //{
            //    var placedTetraSticks = solution.RowIndexes.Select(idx => rows[idx]).ToImmutableList();
            //    _synchronizationContext.Post(_onSolutionFound, placedTetraSticks);
            //}

            var solution = dlx.Solve(matrix, d => d, r => r, 75).First();

            {
                var placedTetraSticks = solution.RowIndexes.Select(idx => rows[idx]).ToImmutableList();
                _synchronizationContext.Post(_onSolutionFound, placedTetraSticks);
            }

            _synchronizationContext.Post(_onDoneSolving);
        }
Пример #4
0
        public void SecondaryColumnsCanBeCoveredOnlyOnceLikePrimaryColumns()
        {
            // Arrange
            var matrix = new List <List <int> >
            {
                new List <int> {
                    1, 0, 0, 0, 1
                },                             // 0
                new List <int> {
                    0, 1, 1, 0, 0
                },                             // 1
                new List <int> {
                    1, 0, 0, 1, 0
                },                             // 2
                new List <int> {
                    0, 0, 1, 1, 0
                },                             // 3
                new List <int> {
                    0, 1, 0, 0, 1
                },                             // 4
                new List <int> {
                    0, 0, 1, 0, 1
                }                              // 5
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix, d => d, r => r, 4).ToList();

            // Assert
            AssertSolutions(solutions, new[] {
                new[] { 1, 2 }
            });
        }
Пример #5
0
        public void SolutionFoundEventFiresOnceForEachSolutionTaken(int numSolutionsToTake)
        {
            var matrix = new[, ]
            {
                { 1, 0, 0, 0 },
                { 0, 1, 1, 0 },
                { 1, 0, 0, 1 },
                { 0, 0, 1, 1 },
                { 0, 1, 0, 0 },
                { 0, 0, 1, 0 }
            };
            var dlx = new Dlx();
            var solutionFoundEventArgs = new List <SolutionFoundEventArgs>();

            dlx.SolutionFound += (_, e) => solutionFoundEventArgs.Add(e);

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            dlx.Solve(matrix).Take(numSolutionsToTake).ToList();

            Assert.That(solutionFoundEventArgs.Count, Is.EqualTo(numSolutionsToTake));
            foreach (var index in Enumerable.Range(0, numSolutionsToTake))
            {
                Assert.That(solutionFoundEventArgs[index].SolutionIndex, Is.EqualTo(index));
            }
        }
Пример #6
0
        public Sudoku ResoudreSudoku(Sudoku s)
        {
            var internalRows = BuildInternalRowsForGrid(s);
            var dlxRows      = BuildDlxRows(internalRows);
            var solutions    = new Dlx()
                               .Solve(dlxRows, d => d, r => r)
                               .Where(solution => VerifySolution(internalRows, solution))
                               .ToImmutableList();

            Console.WriteLine();

            if (solutions.Any())
            {
                Console.WriteLine($"First solution (of {solutions.Count}):");
                Console.WriteLine();
                DrawSolution(internalRows, solutions.First());
                Console.WriteLine();
            }
            else
            {
                Console.WriteLine("No solutions found!");
            }
            Console.Read();
            return(s);
        }
Пример #7
0
        public void CanGetTheFirstSolutionUsingFirst()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 1, 0, 0, 0 },
                { 0, 1, 1, 0 },
                { 1, 0, 0, 1 },
                { 0, 0, 1, 1 },
                { 0, 1, 0, 0 },
                { 0, 0, 1, 0 }
            };
            var dlx = new Dlx();
            var numSolutionFoundEventsRaised = 0;

            dlx.SolutionFound += (_, __) => numSolutionFoundEventsRaised++;

            // Act
            var firstSolution = dlx.Solve(matrix).First();

            // Assert
            Assert.That(firstSolution.RowIndexes, Is.EquivalentTo(new[] { 0, 3, 4 })
                        .Or
                        .EquivalentTo(new[] { 1, 2 })
                        .Or
                        .EquivalentTo(new[] { 2, 4, 5 }));
            Assert.That(numSolutionFoundEventsRaised, Is.EqualTo(1));
        }
Пример #8
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));
        }
Пример #9
0
        public void CanGetTheFirstSolutionUsingFirst()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 1, 0, 0, 0 },
                { 0, 1, 1, 0 },
                { 1, 0, 0, 1 },
                { 0, 0, 1, 1 },
                { 0, 1, 0, 0 },
                { 0, 0, 1, 0 }
            };
            var dlx = new Dlx();
            var numSolutionFoundEventsRaised = 0;

            dlx.SolutionFound += (_, __) => numSolutionFoundEventsRaised++;

            // Act
            var firstSolution = dlx.Solve(matrix).First();

            AssertSolution(firstSolution, new[] {
                new[] { 0, 3, 4 },
                new[] { 1, 2 },
                new[] { 2, 4, 5 },
            });
            Assert.Equal(numSolutionFoundEventsRaised, 1);
        }
Пример #10
0
        public IEnumerable <PiecePlacement> Solve()
        {
            BuildMatrixAndDictionary();
            var dlx      = new Dlx();
            var solution = dlx.Solve(_data, d => d, r => r.MatrixRow).First();

            return(solution.RowIndexes.Select(rowIndex => _data[rowIndex].PiecePlacement));
        }
Пример #11
0
        public SudokuLib.Sudoku Solve(SudokuLib.Sudoku sudoku)
        {
            var matrix            = createMatrix(sudoku);
            var dlx               = new Dlx();
            var firstTwoSolutions = dlx.Solve(matrix).First();

            SudokuLib.Sudoku toReturn = createSudoku(firstTwoSolutions);
            return(toReturn);
        }
Пример #12
0
 public Solver(IEnumerable <Piece> pieces, int boardSize)
 {
     _cancellationTokenSource = new CancellationTokenSource();
     _dlx    = new Dlx(_cancellationTokenSource.Token);
     _pieces = pieces.ToArray();
     _board  = new Board(boardSize);
     _board.ForceColourOfSquareZeroZeroToBeWhite();
     SearchSteps = new ConcurrentQueue <SearchStep>();
 }
Пример #13
0
        public void EmptyMatrixReturnsNoSolutions()
        {
            // Arrange
            var matrix = new bool[0, 0];
            var dlx    = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix);

            // Assert
            Assert.That(solutions.Count(), Is.EqualTo(0));
        }
Пример #14
0
        public void EmptyMatrixReturnsNoSolutions()
        {
            // Arrange
            var matrix = new bool[0, 0];
            var dlx    = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix);

            // Assert
            Assert.Empty(solutions);
        }
Пример #15
0
        //Création d'une méthode qui prend en entrée un string (le sudoku non résolu) et qui renvoie un string (le sudoku résolu).
        //De base le code duquel on s'est inspiré ne renvoyait rien, la sortie était sous forme d'un Console.WriteLine()
        private static string Sudokusolution(string sudoku)
        {
            //Récupération du sudoku à résoudre depuis le string en entrée et transfert dans une ImmutableList.
            var grid = new Grid(ImmutableList.Create(
                                    sudoku.Substring(0, 9),
                                    sudoku.Substring(9, 9),
                                    sudoku.Substring(18, 9),
                                    sudoku.Substring(27, 9),
                                    sudoku.Substring(36, 9),
                                    sudoku.Substring(45, 9),
                                    sudoku.Substring(54, 9),
                                    sudoku.Substring(63, 9),
                                    sudoku.Substring(72, 9)));

            var internalRows = BuildInternalRowsForGrid(grid);
            var dlxRows      = BuildDlxRows(internalRows);

            var solutions = new Dlx()
                            .Solve(BuildDlxRows(internalRows), d => d, r => r)
                            .Where(solution => VerifySolution(internalRows, solution))
                            .ToImmutableList();

            if (solutions.Any())
            {
                //Enlever commentaire pour afficher les solutions dans la console

                //Console.WriteLine($"First solution (of {solutions.Count}):");
                //Console.WriteLine();
                //SolutionToGrid(internalRows, solutions.First()).Draw();
                //Console.WriteLine();

                //Ajout de ce bout de code pour avoir une sortie de type string contenant le sudoku résolu.
                string s = "";
                for (int i = 0; i <= 8; i++)
                {
                    for (int j = 0; j <= 8; j++)
                    {
                        s += SolutionToGrid(internalRows, solutions.First()).ValueAt(i, j).ToString();
                    }
                }

                return(s);
            }
            else
            {
                //Console.WriteLine("No solutions found!");
                return("No solutions found!");
            }
        }
Пример #16
0
        public void MatrixWithSingleRowOfAllZerosReturnsNoSolutions()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 0, 0, 0 }
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix).ToList();

            // Assert
            Assert.That(solutions, Has.Count.EqualTo(0));
        }
Пример #17
0
        public void MatrixWithSingleRowOfAllZerosReturnsNoSolutions()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 0, 0, 0 }
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix).ToList();

            // Assert
            Assert.Empty(solutions);
        }
Пример #18
0
        private static void Main()
        {
            var puzzle       = new Puzzle();
            var internalRows = InternalRowBuilder.BuildInternalRows(puzzle);
            var dlxMatrix    = DlxMatrixBuilder.BuildDlxMatrix(puzzle, internalRows);

            var dlx      = new Dlx();
            var solution = dlx.Solve(dlxMatrix, rows => rows, row => row.Bits).FirstOrDefault();

            if (solution != null)
            {
                DumpSolutionSimple(solution, dlxMatrix);
                Console.WriteLine();
                DumpSolutionCube(puzzle, solution, dlxMatrix);
            }
        }
Пример #19
0
        public void ExactCoverProblemsWithNoSolutionsTest()
        {
            Func <int, string> makeLabel = numSolutions => string.Format(
                "Expected no solutions but got {0}",
                numSolutions);

            var arbMatrix = Arb.From(GenMatrixOfIntWithNoSolutions());

            var property = Prop.ForAll(arbMatrix, matrix =>
            {
                var solutions = new Dlx().Solve(matrix).ToList();
                return((!solutions.Any()).Label(makeLabel(solutions.Count())));
            });

            Check.One(Config, property);
        }
Пример #20
0
        private bool TryRemoveNumber(int index)
        {
            int number = _puzzle[index];

            _puzzle[index] = 0;
            SudokuExactCover();
            MakeExactCoverGridFromSudoku();
            IEnumerable <Solution> solutions = new Dlx().Solve(_problemMatrix);

            if (solutions.Count() == 1)
            {
                return(true);
            }
            _puzzle[index] = number;
            return(false);
        }
Пример #21
0
        public void CancelledEventFiresUsingCancellationToken()
        {
            var matrix = new bool[0, 0];
            var cancellationTokenSource = new CancellationTokenSource();
            var dlx = new Dlx(cancellationTokenSource.Token);
            var cancelledEventHasBeenRaised = false;

            dlx.Cancelled += (_, __) => cancelledEventHasBeenRaised = true;
            dlx.Started   += (_, __) => cancellationTokenSource.Cancel();

            var thread = new Thread(() => dlx.Solve(matrix).FirstOrDefault());

            thread.Start();
            thread.Join();

            Assert.True(cancelledEventHasBeenRaised);
        }
Пример #22
0
        private static void Demo2()
        {
            var matrix = new[, ]
            {
                { 1, 0, 0, 0 },
                { 0, 1, 1, 0 },
                { 1, 0, 0, 1 },
                { 0, 0, 1, 1 },
                { 0, 1, 0, 0 },
                { 0, 0, 1, 0 }
            };

            var dlx       = new Dlx();
            var solutions = dlx.Solve(matrix);

            PrintSolutions(matrix, solutions);
        }
Пример #23
0
        public void MatrixWithSingleRowOfAllOnesReturnsOneSolution()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 1, 1, 1 }
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix).ToList();

            // Assert
            AssertSolutions(solutions, new[] {
                new[] { 0 }
            });
        }
Пример #24
0
        public void MatrixWithSingleRowOfAllOnesReturnsOneSolution()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 1, 1, 1 }
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix).ToList();

            // Assert
            Assert.That(solutions, Has.Count.EqualTo(1));
            Assert.That(solutions[0].RowIndexes.Count(), Is.EqualTo(1));
            Assert.That(solutions.Select(s => s.RowIndexes), Contains.Item(new[] { 0 }));
        }
Пример #25
0
        public void SolveWithArbitraryDataStuctureAndCustomPredicate()
        {
            // Arrange
            var data = new List <Tuple <char[], string> >
            {
                Tuple.Create(new[] { 'X', 'O', 'O' }, "Some data associated with row 0"),
                Tuple.Create(new[] { 'O', 'X', 'O' }, "Some data associated with row 1"),
                Tuple.Create(new[] { 'O', 'O', 'X' }, "Some data associated with row 2")
            };

            // Act
            var solutions = new Dlx().Solve(data, d => d, r => r.Item1, c => c == 'X').ToList();

            // Assert
            Assert.That(solutions, Has.Count.EqualTo(1));
            Assert.That(solutions.Select(s => s.RowIndexes), Contains.Item(new[] { 0, 1, 2 }));
        }
Пример #26
0
        public void SolveWithMatrixOfInt()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 1, 0, 0 },
                { 0, 1, 0 },
                { 0, 0, 1 }
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix).ToList();

            // Assert
            Assert.That(solutions, Has.Count.EqualTo(1));
            Assert.That(solutions.Select(s => s.RowIndexes), Contains.Item(new[] { 0, 1, 2 }));
        }
Пример #27
0
        public void SolveWithArbitraryDataStucture()
        {
            // Arrange
            var data = new List <Tuple <int[], string> >
            {
                Tuple.Create(new[] { 1, 0, 0 }, "Some data associated with row 0"),
                Tuple.Create(new[] { 0, 1, 0 }, "Some data associated with row 1"),
                Tuple.Create(new[] { 0, 0, 1 }, "Some data associated with row 2")
            };

            // Act
            var solutions = new Dlx().Solve(data, d => d, r => r.Item1).ToList();

            // Assert
            AssertSolutions(solutions, new[] {
                new[] { 0, 1, 2 }
            });
        }
Пример #28
0
        public void SolveWithArbitraryDataStuctureAndCustomPredicate()
        {
            // Arrange
            var data = new List <Tuple <char[], string> >
            {
                Tuple.Create(new[] { 'X', 'O', 'O' }, "Some data associated with row 0"),
                Tuple.Create(new[] { 'O', 'X', 'O' }, "Some data associated with row 1"),
                Tuple.Create(new[] { 'O', 'O', 'X' }, "Some data associated with row 2")
            };

            // Act
            var solutions = new Dlx().Solve(data, d => d, r => r.Item1, c => c == 'X').ToList();

            // Assert
            AssertSolutions(solutions, new[] {
                new[] { 0, 1, 2 }
            });
        }
Пример #29
0
        public void CancelledEventFiresUsingCancellationToken()
        {
            var matrix = new bool[0, 0];
            var cancellationTokenSource = new CancellationTokenSource();
            var dlx = new Dlx(cancellationTokenSource.Token);
            var cancelledEventHasBeenRaised = false;

            dlx.Cancelled += (_, __) => cancelledEventHasBeenRaised = true;
            dlx.Started   += (_, __) => cancellationTokenSource.Cancel();

            // ReSharper disable once ReturnValueOfPureMethodIsNotUsed
            var thread = new Thread(() => dlx.Solve(matrix).FirstOrDefault());

            thread.Start();
            thread.Join();

            Assert.That(cancelledEventHasBeenRaised, Is.True, "Expected the Cancelled event to have been raised");
        }
Пример #30
0
        public void ExactCoverProblemsWithSingleSolutionTest()
        {
            Func <int, string> makeLabel = numSolutions => string.Format(
                "Expected exactly one solution but got {0}",
                numSolutions);

            var arbMatrix = Arb.From(GenMatrixOfIntWithSingleSolution());

            var property = Prop.ForAll(arbMatrix, matrix =>
            {
                var solutions = new Dlx().Solve(matrix).ToList();
                var p1        = (solutions.Count() == 1).Label(makeLabel(solutions.Count()));
                var p2        = CheckSolutions(solutions, matrix);
                return(FsCheckUtils.And(p1, p2));
            });

            Check.One(Config, property);
        }
Пример #31
0
        public void SolveWithMatrixOfCharAndCustomPredicate()
        {
            // Arrange
            var matrix = new[, ]
            {
                { 'X', 'O', 'O' },
                { 'O', 'X', 'O' },
                { 'O', 'O', 'X' }
            };
            var dlx = new Dlx();

            // Act
            var solutions = dlx.Solve(matrix, c => c == 'X').ToList();

            // Assert
            Assert.That(solutions, Has.Count.EqualTo(1));
            Assert.That(solutions.Select(s => s.RowIndexes), Contains.Item(new[] { 0, 1, 2 }));
        }
Пример #32
0
        public void Solve()
        {
            var internalRows = BuildInternalRows(_puzzle);
            var dlxRows = BuildDlxRows(internalRows);

            var dlx = new Dlx(_cancellationToken);

            dlx.SearchStep += (_, args) =>
            {
                _searchStepCount++;
                var searchStepInternalRows = args.RowIndexes
                    .Select(rowIndex => internalRows[rowIndex])
                    .ToImmutableList();
                var eventArgs = new SearchStepEventArgs(_searchStepCount, searchStepInternalRows);
                var handler = SearchStep;
                handler?.Invoke(this, eventArgs);
            };

            var firstSolution = dlx.Solve(dlxRows, d => d, r => r).FirstOrDefault();

            if (firstSolution != null)
            {
                var solutionInternalRows = firstSolution.RowIndexes
                    .Select(rowIndex => internalRows[rowIndex])
                    .ToImmutableList();
                var eventArgs = new SolutionFoundEventArgs(_searchStepCount, solutionInternalRows);
                var handler = SolutionFound;
                handler?.Invoke(this, eventArgs);
            }
            else
            {
                var eventArgs = new NoSolutionFoundEventArgs(_searchStepCount);
                var handler = NoSolutionFound;
                handler?.Invoke(this, eventArgs);
            }
        }
Пример #33
0
        private static void Main()
        {
            // http://puzzles.telegraph.co.uk/site/search_puzzle_number?id=27744
            var grid = new Grid(ImmutableList.Create(
                "6 4 9 7 3",
                "  3    6 ",
                "       18",
                "   18   9",
                "     43  ",
                "7   39   ",
                " 7       ",
                " 4    8  ",
                "9 8 6 4 5"));

            grid.Draw();

            var internalRows = BuildInternalRowsForGrid(grid);
            var dlxRows = BuildDlxRows(internalRows);
            var solutions = new Dlx()
                .Solve(dlxRows, d => d, r => r)
                .Where(solution => VerifySolution(internalRows, solution))
                .ToImmutableList();

            Console.WriteLine();

            if (solutions.Any())
            {
                Console.WriteLine($"First solution (of {solutions.Count}):");
                Console.WriteLine();
                DrawSolution(internalRows, solutions.First());
                Console.WriteLine();
            }
            else
            {
                Console.WriteLine("No solutions found!");
            }
        }
Пример #34
0
        private void SolvePuzzleInBackground()
        {
            var rooms = _puzzle.Rooms;
            var initialValues = _puzzle.InitialValues;

            var numRows = rooms.SelectMany(r => r.Cells).Max(c => c.Row) + 1;
            var numCols = rooms.SelectMany(r => r.Cells).Max(c => c.Col) + 1;
            var maxValue = rooms.Max(r => r.Cells.Count);

            var internalRows1 = rooms.SelectMany(room => BuildInternalRowsForRoom(rooms, initialValues, room));
            var internalRows2 = initialValues.Select(t => BuildInternalRow(rooms, t.Item1, t.Item2, true));
            var internalRows = internalRows1.Concat(internalRows2).ToImmutableList();

            var dlxRows = BuildDlxRows(rooms, numRows, numCols, maxValue, internalRows);

            var numRowColPrimaryColumns = numRows * numCols;
            var numCellWithinRoomPrimaryColumns = rooms.Sum(r => r.Cells.Count);
            var numPrimaryColumns = numRowColPrimaryColumns + numCellWithinRoomPrimaryColumns;

            var dlx = new Dlx(_cancellationToken);

            dlx.SearchStep += (_, searchStepEventArgs) =>
            {
                var subsetOfInternalRows = searchStepEventArgs.RowIndexes.Select(idx => internalRows[idx]).ToImmutableList();
                _synchronizationContext.Post(_onSearchStep, subsetOfInternalRows);
            };

            var firstSolution = dlx.Solve(dlxRows, d => d, r => r, numPrimaryColumns).FirstOrDefault();

            if (firstSolution != null)
            {
                var subsetOfInternalRows = firstSolution.RowIndexes.Select(idx => internalRows[idx]).ToImmutableList();
                _synchronizationContext.Post(_onSolutionFound, subsetOfInternalRows);
            }
        }
Пример #35
0
        private static Grid Solve(SamplePuzzle samplePuzzle)
        {
            var rooms = samplePuzzle.Rooms;
            var initialValues = samplePuzzle.InitialValues;

            var numRows = rooms.SelectMany(r => r.Cells).Max(c => c.Row) + 1;
            var numCols = rooms.SelectMany(r => r.Cells).Max(c => c.Col) + 1;
            var maxValue = rooms.Max(r => r.Cells.Count);

            var internalRows1 = rooms.SelectMany(room => BuildInternalRowsForRoom(rooms, initialValues, room));
            var internalRows2 = initialValues.Select(t => BuildInternalRow(rooms, t.Item1, t.Item2, true));
            var internalRows = internalRows1.Concat(internalRows2).ToImmutableList();

            var dlxRows = BuildDlxRows(rooms, numRows, numCols, maxValue, internalRows);

            var numRowColPrimaryColumns = numRows * numCols;
            var numCellWithinRoomPrimaryColumns = rooms.Sum(r => r.Cells.Count);
            var numPrimaryColumns = numRowColPrimaryColumns + numCellWithinRoomPrimaryColumns;

            var dlx = new Dlx();
            var solutions = dlx.Solve(dlxRows, d => d, r => r, numPrimaryColumns).ToList();
            Console.WriteLine($"Number of solutions found: {solutions.Count}");
            var firstSolution = solutions.FirstOrDefault();

            if (firstSolution == null) return null;

            var subsetOfInternalRows = firstSolution.RowIndexes.Select(idx => internalRows[idx]).ToImmutableList();
            var orderedSubsetOfInternalRows = subsetOfInternalRows.OrderBy(t => t.Item1.Row).ThenBy(t => t.Item1.Col);
            var rowStrings = Enumerable.Range(0, numRows).Select(row => string.Join("", orderedSubsetOfInternalRows.Skip(row * numCols).Take(numRows).Select(t => t.Item2)));
            var grid = new Grid(rowStrings.ToImmutableList());
            return grid;
        }