private void Fetch(uint value, SimpleList <int> intersection, SudokuRegion intersected, SudokuState state, ICollection <IEvent> events) { IEvent result = NoReduction.Instance; var mask = ~value; foreach (var index in intersected) { // items in the shared section should be skipped. if (intersection.Contains(index)) { continue; } var test = state.And <ReducePointingPairs>(index, mask); if (test is ValueFound) { events.Add(test); } else if (test is ReducedOption) { result = test; } } if (result is ReducedOption) { events.Add(ReducedOptions.Ctor <ReduceNakedPairs>()); } }
private void ReduceRegion(int skip, SudokuRegion region, SudokuState state, ICollection <IEvent> events) { var quad = 0u; buffer.Clear(); foreach (var index in region.Skip(skip)) { var value = state[index]; if (SudokuCell.Count(value) < 4) { quad |= value; // Joined the represent more then 3 values. if (SudokuCell.Count(quad) > 4 || buffer.Count > 3) { return; } buffer.Add(index); } } if (buffer.Count == 4) { Fetch(quad, buffer, region, state, events); } }
private void Fetch(uint quad, SimpleList <int> buffer, SudokuRegion region, SudokuState state, ICollection <IEvent> events) { var reduced = false; var mask = ~quad; foreach (var index in region) { if (buffer.Contains(index)) { continue; } var result = state.And <ReduceNakedTriples>(index, mask); if (result is ValueFound) { events.Add(result); } else if (result is ReducedOption) { reduced = true; } } if (reduced) { events.Add(ReducedOptions.Ctor <ReduceNakedTriples>()); } }
private void Fetch(uint nakedPair, SudokuRegion region, SudokuState state, ICollection <IEvent> events) { IEvent result = NoReduction.Instance; var mask = ~nakedPair; foreach (var index in region) { var value = state[index]; if (value != nakedPair) { var test = state.And <ReduceNakedPairs>(index, mask); if (test is ValueFound) { events.Add(test); } else if (test is ReducedOption) { result = test; } } } if (result is ReducedOption) { events.Add(ReducedOptions.Ctor <ReduceNakedPairs>()); } }
private void ReduceRegion(uint pair, SudokuRegion region, SudokuState state, ICollection <IEvent> events) { HiddenPairs.Clear(); foreach (var index in region) { var and = state[index] & pair; // at least on of the two is pressent. if (and != 0) { // If not both are present or we already had 2, return. if (and != pair || HiddenPairs.Count > 1) { return; } HiddenPairs.Add(index); } } if (HiddenPairs.Count == 2) { Fetch(pair, HiddenPairs, state, events); } }
private void ReduceRegion(SudokuRegion region, SudokuState state, ICollection <IEvent> events) { var nakedPair = 0u; var count = 0; foreach (var index in region) { var value = state[index]; // nothing found yet. if (nakedPair == default) { if (SudokuCell.Count(value) == 2) { nakedPair = value; count++; } } // Equal to the first (potential) naked pair. else if (value == nakedPair && count++ > 2) { throw new InvalidPuzzleException(); } } if (count > 1) { Fetch(nakedPair, region, state, events); } }
private void CheckCells(SudokuState state, SudokuRegion region, uint singleValue, ICollection <IEvent> events) { var hidden = NoIndex; foreach (var index in region) { var value = state[index]; // the cell has the value. if ((singleValue & value) != 0) { // Already value, try next. if (singleValue == value) { return; } // not the first if (hidden != NoIndex) { return; } hidden = index; } } if (hidden == NoIndex) { return; } events.Add(state.And <ReduceHiddenSingles>(hidden, singleValue)); }
/// <summary>Initializes all column regions.</summary> private void InitializeColumnRegions(int size2) { for (var column = 0; column < size2; column++) { var region = new SudokuRegion(SudokuRegionType.Column); Regions.Add(region); for (var height = 0; height < size2; height++) { region.Add(Grid[height, column]); } } }
/// <summary>Initializes all row regions.</summary> private void InitializeRowRegions(int size2) { for (int row = 0; row < size2; row++) { var region = new SudokuRegion(SudokuRegionType.Row); Regions.Add(region); for (int width = 0; width < size2; width++) { region.Add(Grid[row, width]); } } }
public void Solve(uint value, SudokuRegion first, SudokuRegion second, SudokuRegionType otherType, SudokuState state, ICollection <IEvent> events) { buffer.Clear(); for (var index = 0; index < 9; index++) { var indexFirst = first[index]; var indexSecond = second[index]; var joinFirst = state[indexFirst] & value; var joinSecond = state[indexSecond] & value; if (joinFirst == 0) { if (joinSecond != 0) { return; } } else { if (joinSecond == 0 || buffer.Count > 3) { return; } buffer.Add(indexFirst); buffer.Add(indexSecond); } } if (buffer.Count == 4) { var reducded = Fetch( value, first.Intersected.FirstOrDefault(r => r.RegionType == otherType), state, events); reducded |= Fetch( value, second.Intersected.FirstOrDefault(r => r.RegionType == otherType), state, events); if (reducded) { events.Add(ReducedOptions.Ctor <ReduceXWing>()); } } }
/// <summary>Initializes all sub square regions.</summary> private void InitializeSubSquareRegions(int size) { for (var xSub = 0; xSub < size; xSub++) { for (var ySub = 0; ySub < size; ySub++) { var region = new SudokuRegion(SudokuRegionType.Block); Regions.Add(region); for (var x = 0; x < size; x++) { for (var y = 0; y < size; y++) { region.Add(Grid[xSub * size + x, ySub * size + y]); } } } } }
/// <summary>Returns true if the other has a intersection with this region of at least 2 cells, but is not the same region.</summary> public bool HasIntersectionOf2OrMoreSquares(SudokuRegion other) { if (other == this) { return(false); } var count = 0; foreach (var index in this) { if (other.Contains(index)) { count++; } if (count > 1) { break; } } return(count > 1); }
private void Solve(SudokuState state, SudokuRegion region, SudokuRegion intersected, uint value, ICollection <IEvent> events) { var count = 0; foreach (var index in region) { if ((state[index] & value) != 0) { if (intersection.Contains(index)) { count++; } else { return; } } } if (count > 1) { Fetch(value, intersection, intersected, state, events); } }
private bool Fetch(uint value, SudokuRegion region, SudokuState state, ICollection <IEvent> events) { var reducded = false; var mask = ~value; foreach (var index in region) { if (buffer.Contains(index)) { continue; } var result = state.And <ReduceXWing>(index, mask); if (result is ValueFound) { events.Add(result); } else if (result is ReducedOption) { reducded = true; } } return(reducded); }