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 })); }
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)); } }
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); }
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 } }); }
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)); } }
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); }
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)); }
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)); }
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); }
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)); }
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); }
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>(); }
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)); }
public void EmptyMatrixReturnsNoSolutions() { // Arrange var matrix = new bool[0, 0]; var dlx = new Dlx(); // Act var solutions = dlx.Solve(matrix); // Assert Assert.Empty(solutions); }
//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!"); } }
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)); }
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); }
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); } }
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); }
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); }
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); }
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); }
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 } }); }
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 })); }
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 })); }
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 })); }
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 } }); }
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 } }); }
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"); }
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); }
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 })); }
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); } }
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!"); } }
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); } }
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; }