Sudoku: Difference between revisions

1,024 bytes added ,  2 years ago
m
Line 1,834:
using System.Runtime.CompilerServices;
 
namespace SodukoBestFirstSearchSodukoFastMemoBFS {
internal staticreadonly classrecord SudokuBFSstruct {Square (int Row, int Col);
internal record Constraints (IEnumerable<int> ConstrainedRange, Square Square);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal class Cache : Dictionary<Square, IEnumerable<Constraints>> { };
private static int RowCol(int rc) => rc <= 2 ? 0 : rc <= 5 ? 3 : 6;
internal record CacheGrid (int[][] Grid, Cache Cache);
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];
 
internal static class SudokuFastMemoBFS {
private static readonly int[] range = Range(1, 9).ToArray();
privateinternal static boolU SolveFwd<T, U>(this int[][]T griddata, IEnumerableFunc<(IEnumerable<int> constraintsT, intU> row,f) int col)=> cellsf(data) {;
if (!cells.Any())
return true;
 
[MethodImpl(MethodImplOptions.AggressiveInlining)]
var (constraints, row, col) = cells.First();
private static int RowCol(int rc) => rc <= 2 ? 0 : rc <= 5 ? 3 : 6;
foreach (var i in range.Except(constraints)) {
 
grid[row][col] = i;
private static bool Solve(this CacheGrid cg, IEnumerable<Constraints> constraints, int finished) {
if (grid.Solve(grid.SortedCells()))
foreach (var sc in constraints) { return true;
var (constraints, row, col) = cellssc.First()Square;
foreach (var i in rangesc.Except(constraints)ConstrainedRange) {
cg.Grid[row][col] = i;
if (cg.Cache.Count == finished || cg.Solve(cg.Next(sc.Square), finished))
return true;
if (!cells.Any()) }
gridcg.Grid[row][col] = i0;
return false;
}
grid[row][col] = 0;
return false;
}
 
private static readonly int[] Unmarked = new[] { 0 };
 
private static readonly int[] domain = Range(0, 9).ToArray();
private static readonly int[] range = Range(1, 9).ToArray();
 
private static IEnumerable<int>bool GetBoxValid(this int[][] grid, int row, int col, int val) =>{
for (var i = 0; i < 9; i++)
if (grid[row][i] == val || grid[i][col] == val)
return false;
for (var r = RowCol(row); r < RowCol(row) + 3; r++)
for (var c = RowCol(col); c < RowCol(col) + 3; c++)
if (grid.Solve(grid.SortedCells())[r][c] == val)
return false;
return true;
}
 
private static IEnumerable<int> Constraints(this int[][] grid, int row, int col) =>
range.Where(val => grid[.Valid(row], col, val));
 
.Union(domain.Select(r => grid[r][col]))
private static IEnumerable<Constraints> Next(this CacheGrid cg, Square square) =>
.Union(GetBox(grid, row, col))
cg.ExceptCache.ContainsKey(Unmarkedsquare);
? cg.Cache[square]
: cg.Cache[square]=cg.Grid.SortedCells();
 
private static IEnumerable<(IEnumerable<int> constraints,int row, int col)Constraints> SortedCells(this int[][] grid) =>
(from row in domain
from col in domain
where grid[row][col] == 0
let cell = (constraints:new Constraints(grid.Constraints(row, col), new Square(row, col))
orderbygroup cell by cell.constraintsConstrainedRange.Count() descendinginto groupedCells
selectorderby cell;groupedCells.Key ascending
select groupedCells).First();
 
private static int[][]CacheGrid Parse(string input) =>
input
.Select((c, i) => (index: i, val: int.Parse(c.ToString())))
.GroupBy(id => id.index / 9)
.Select(grp => grp.Select(id => id.val).ToArray())
.ToArray();
.Fwd(grid => new CacheGrid(grid, new Cache()));
 
public static string AsString(this int[][] grid) =>
string.Join('\n', grid.Select(row => string.Concat(row)));
 
public static int[][] Run(string input) {
var gridcg = Parse(input);
returnvar gridmarked = cg.Solve(gridGrid.SortedCellsSelectMany())row ?=> gridrow.Where(c :=> newc int[][]> { Array0)).Empty<int>Count() };
return cg.Solve(cg.Grid.SortedCells(), 80 - marked) ? cg.Grid : new int[][] { Array.Empty<int>() };
}
}