public Puzzle Solve(Puzzle puzzle) { var context = new PlausibilitySolver.SolverContext(puzzle.Columns, puzzle.Rows); Preeliminate(puzzle, context); return(new PlausibilitySolver().Solve(puzzle, context, puzzle.FilledCellRanges.ToList())); }
public void Preeliminate(Puzzle puzzle, PlausibilitySolver.SolverContext context) { foreach (var cellRange in puzzle.NotFullyFilledCellRanges) { foreach (var word in puzzle.Words.Where(w => puzzle.Matches(cellRange, w))) { // Run elimination descent for each possible start combination var candidate = puzzle.SetWord(cellRange, word); Preeliminate(candidate, context, cellRange); } } }
public void Preeliminate(Puzzle puzzle, PlausibilitySolver.SolverContext context, CellRange previousRange) { //Console.WriteLine(puzzle); if (context.TriedCount % 500 == 0) { Console.Write($"\rEliminating C:{context.count} D:{context.depth} T:{context.TriedCount}"); } var overlappingRanges = puzzle.NotFullyFilledCellRanges.Where(r => !r.Equals(previousRange) && r.Overlaps(previousRange)).ToList(); foreach (var cellRange in overlappingRanges) { var words = puzzle.Words.Where(w => puzzle.Matches(cellRange, w)).ToList(); if (words.Count() == 0) { if (puzzle.IsPartialSolution()) { Console.WriteLine("Rejected partial solution:"); Console.WriteLine(puzzle); puzzle.IsPartialSolution(); Environment.Exit(-1); } context.AddTried(puzzle.cells); return; } if (context.depth >= 1) { return; } foreach (var word in words) { var candidate = puzzle.SetWord(cellRange, word); if (!context.AlreadyTried(candidate)) { context.depth++; Preeliminate(candidate, context, cellRange); context.depth--; } } } }