Sudoku: Difference between revisions

Content added Content deleted
Line 1,839: Line 1,839:
[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(int[][] grid, int row, int col) =>
from r in Range(RowCol(row), 3)
from c in Range(RowCol(col), 3)
select grid[r][c];


private static IEnumerable<(int r,int c)> GetBoxIndices(int row, int col) =>
private static readonly int[] range = Range(1, 9).ToArray();
from r in Range(RowCol(row), 3)
from c in Range(RowCol(col), 3)
select (r,c);

private static readonly Dictionary<(int r, int c), List<(int r, int c)>> Boxes =
(from row in Range(0, 3).Select(i => i * 3)
from col in Range(0, 3).Select(i => i * 3)
select ((row, col), GetBoxIndices(row, col)))
.ToDictionary(kvp => kvp.Item1, kvp => kvp.Item2.ToList());

private static IEnumerable<int> GetBox(this int[][] grid, int row, int col) =>
Boxes[(RowCol(row), RowCol(col))].Select(p=>grid[p.r][p.c]);

private static readonly int[] Domain = Range(1, 9).ToArray();

private static bool Solve(this int[][] grid, List<(int, int)> cells, int idx) {
private static bool Solve(this int[][] grid, List<(int, int)> cells, int idx) {
if (idx == 81)
if (idx == 81)
Line 1,861: Line 1,850:


var (r, c) = cells[idx];
var (r, c) = cells[idx];
foreach (var i in Domain.Except(grid.Hints(r,c))) {
foreach (var i in range.Except(grid.Hints(r,c))) {
grid[r][c] = i;
grid[r][c] = i;
if (grid.Solve(cells, idx + 1))
if (grid.Solve(cells, idx + 1))
Line 1,871: Line 1,860:


private static readonly int[] Unmarked = new[] { 0 };
private static readonly int[] Unmarked = new[] { 0 };

private static readonly int[] domain = Range(0, 9).ToArray();


private static IEnumerable<int> Hints(this int[][] grid, int row, int col) =>
private static IEnumerable<int> Hints(this int[][] grid, int row, int col) =>
grid[row]
grid[row]
.Union(Range(0, 9).Select(r => grid[r][col]))
.Union(domain.Select(r => grid[r][col]))
.Union(grid.GetBox(row, col))
.Union(GetBox(grid, row, col))
.Except(Unmarked);
.Except(Unmarked);


private static IEnumerable<(int, int)> SortedCells(this int[][] grid) =>
private static IEnumerable<(int, int)> SortedCells(this int[][] grid) =>
from row in Range(0,9)
from row in domain
from col in Range(0,9)
from col in domain
let cell = (count: grid[row][col] > 0 ? 10 : Hints(grid, row, col).Count(), cell: (row, col))
let cell = (count: grid[row][col] > 0 ? 10 : Hints(grid, row, col).Count(), cell: (row, col))
orderby cell.count descending
orderby cell.count descending