Sudoku: Difference between revisions
Content added Content deleted
Line 1,826: | Line 1,826: | ||
}</lang> |
}</lang> |
||
=== "Smart" |
=== Best First Search "Smart" Backtrack Solution=== |
||
<!-- By Martin Freedman, 20/11/2021 --> |
<!-- By Martin Freedman, 20/11/2021 --> |
||
<lang csharp>using System.Linq; |
<lang csharp>using System.Linq; |
||
Line 1,834: | Line 1,834: | ||
using System.Runtime.CompilerServices; |
using System.Runtime.CompilerServices; |
||
namespace |
namespace SodukoBestFirstSearch { |
||
internal static class |
internal static class SudokuBFS { |
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||
private static int RowCol(int rc) => rc <= 2 ? 0 : rc <= 5 ? 3 : 6; |
private static int RowCol(int rc) => rc <= 2 ? 0 : rc <= 5 ? 3 : 6; |
||
private static IEnumerable<int> GetBox( |
private static IEnumerable<int> GetBox(int[][] grid, int row, int col) => |
||
from r in Range(RowCol(row), 3) |
from r in Range(RowCol(row), 3) from c in Range(RowCol(col), 3) select grid[r][c]; |
||
from c in Range(RowCol(col), 3) |
|||
⚫ | |||
private static readonly int[] range = Range(1, 9).ToArray(); |
private static readonly int[] range = Range(1, 9).ToArray(); |
||
private static bool Solve(this int[][] grid, |
private static bool Solve(this int[][] grid, IEnumerable<(IEnumerable<int> constraints, int row, int col)> cells) { |
||
if ( |
if (!cells.Any()) |
||
return true; |
return true; |
||
var ( |
var (constraints, row, col) = cells.First(); |
||
foreach (var i in range.Except( |
foreach (var i in range.Except(constraints)) { |
||
grid[ |
grid[row][col] = i; |
||
if (grid.Solve( |
if (grid.Solve(grid.SortedCells())) |
||
return true; |
return true; |
||
} |
} |
||
grid[ |
grid[row][col] = 0; |
||
return false; |
return false; |
||
} |
} |
||
Line 1,862: | Line 1,860: | ||
private static readonly int[] domain = Range(0, 9).ToArray(); |
private static readonly int[] domain = Range(0, 9).ToArray(); |
||
private static IEnumerable<int> |
private static IEnumerable<int> Constraints(this int[][] grid, int row, int col) => |
||
grid[row] |
grid[row] |
||
.Union(domain.Select(r => grid[r][col])) |
.Union(domain.Select(r => grid[r][col])) |
||
.Union( |
.Union(GetBox(grid, row, col)) |
||
.Except(Unmarked); |
.Except(Unmarked); |
||
private static IEnumerable<(int, int)> SortedCells(this int[][] grid) => |
private static IEnumerable<(IEnumerable<int> constraints,int row, int col)> SortedCells(this int[][] grid) => |
||
from row in domain |
from row in domain |
||
from col in domain |
from col in domain |
||
where grid[row][col] == 0 |
|||
let cell = (constraints: grid.Constraints(row, col), row, col) |
|||
orderby cell.constraints.Count() descending |
|||
⚫ | |||
private static int[][] Parse(string input) => |
private static int[][] Parse(string input) => |
||
Line 1,887: | Line 1,886: | ||
public static int[][] Run(string input) { |
public static int[][] Run(string input) { |
||
var grid = Parse(input); |
var grid = Parse(input); |
||
return grid.Solve(grid.SortedCells()) ? grid : new int[][] { Array.Empty<int>() }; |
|||
var sorted = grid.SortedCells().ToList(); |
|||
return grid.Solve(sorted, hits) ? grid : new int[][] { Array.Empty<int>() }; |
|||
} |
} |
||
} |
} |