Skip to content

Commit

Permalink
TODO NEXT : - complex BUG-Lite
Browse files Browse the repository at this point in the history
and whips/nrczt-chains
  • Loading branch information
ZachIsBeautiful committed Nov 19, 2023
1 parent e4ee6a4 commit 6941580
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 356 deletions.
10 changes: 4 additions & 6 deletions Model/Solver/Possibility/IReadOnlyPossibilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ public static Possibilities DefaultAnd(IReadOnlyPossibilities poss1, IReadOnlyPo
return result;
}

public static Possibilities DefaultInvert(IReadOnlyPossibilities possibilities)
public static Possibilities DefaultDifference(IReadOnlyPossibilities poss1, IReadOnlyPossibilities poss2)
{
var result = new Possibilities();
for (int i = Min; i <= Max; i++)
{
if (!possibilities.Peek(i)) result.Add(i);
}
var result = poss1.Copy();

foreach (var poss in poss2) result.Remove(poss);

return result;
}
Expand Down
2 changes: 1 addition & 1 deletion Model/Solver/Possibility/Possibilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public Possibilities Difference(IReadOnlyPossibilities possibilities)
return new Possibilities(diff, System.Numerics.BitOperations.PopCount((uint) diff));
}

return new Possibilities(); //TODO
return IReadOnlyPossibilities.DefaultDifference(this, possibilities);
}

public Possibilities Invert()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Model.Solver.Strategies.AlternatingChains.ChainAlgorithms;

public class AlternatingChainAlgorithmV4<T> : IAlternatingChainAlgorithm<T> where T : ILinkGraphElement //TODO fix -> Take into account mono-directionnal links
public class AlternatingChainAlgorithmV4<T> : IAlternatingChainAlgorithm<T> where T : ILinkGraphElement
{
public void Run(IStrategyManager view, LinkGraph<T> graph, IAlternatingChainType<T> chainType)
{
Expand Down
122 changes: 41 additions & 81 deletions Model/Solver/Strategies/BUGLiteStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System.Collections.Generic;
using System.Linq;
using Global;
using Global.Enums;
using Model.Solver.Helpers.Changes;
using Model.Solver.Position;
using Model.Solver.Possibility;
using Model.Solver.StrategiesUtility;

namespace Model.Solver.Strategies;

public class BUGLiteStrategy : AbstractStrategy
public class BUGLiteStrategy : AbstractStrategy //TODO check if working => #574
{
public const string OfficialName = "BUG-Lite";
private const OnCommitBehavior DefaultBehavior = OnCommitBehavior.Return;
Expand All @@ -22,7 +21,7 @@ public BUGLiteStrategy() : base(OfficialName, StrategyDifficulty.Hard, DefaultBe

public override void Apply(IStrategyManager strategyManager)
{
Dictionary<BiValue, GridPositions> biValueMap = new();
Dictionary<BiValue, List<Cell>> biValueMap = new();
for (int row = 0; row < 9; row++)
{
for (int col = 0; col < 9; col++)
Expand All @@ -39,109 +38,70 @@ public override void Apply(IStrategyManager strategyManager)

if (!biValueMap.TryGetValue(bi, out var list))
{
list = new GridPositions();
list = new List<Cell>();
biValueMap[bi] = list;
}

list.Add(row, col);
list.Add(new Cell(row, col));
}
}

foreach (var entry in biValueMap)
{
if (entry.Value.Count < 3) continue;

var soloRow = UniquenessHelper.SearchExceptionInUnit(Unit.Row, 2, entry.Value);
if (soloRow == -1) continue;

var soloCol = UniquenessHelper.SearchExceptionInUnit(Unit.Column, 2, entry.Value);
if (soloCol == -1) continue;

var soloMini = UniquenessHelper.SearchExceptionInUnit(Unit.MiniGrid, 2, entry.Value);
if (soloMini == -1) continue;
if (Search(strategyManager, entry.Value, 0, new GridPositions(), entry.Key)) return;
}
}

var miniRow = soloMini / 3;
var miniCol = soloCol / 3;
private bool Search(IStrategyManager strategyManager, List<Cell> cells, int start, GridPositions positions, BiValue bi)
{
for (int i = start; i < cells.Count; i++)
{
positions.Add(cells[i]);

if (soloRow / 3 == miniRow && soloCol / 3 == miniCol)
{
strategyManager.ChangeBuffer.ProposePossibilityRemoval(entry.Key.One, soloRow, soloCol);
strategyManager.ChangeBuffer.ProposePossibilityRemoval(entry.Key.Two, soloRow, soloCol);
}
if (positions.Count >= 3 && positions.Count % 2 == 1 && Try(strategyManager, positions, bi)) return true;

if (strategyManager.ChangeBuffer.NotEmpty() && strategyManager.ChangeBuffer.Commit(this,
new BUGLiteReportBuilder(entry.Value, soloRow, soloCol)))
{
if(OnCommitBehavior == OnCommitBehavior.Return) return;
}
Search(strategyManager, cells, i + 1, positions, bi);

positions.Remove(cells[i]);
}

var asArray = biValueMap.Keys.ToArray();
return false;
}

private bool Try(IStrategyManager strategyManager, GridPositions positions, BiValue bi)
{
var soloRow = UniquenessHelper.SearchExceptionInUnit(Unit.Row, 2, positions);
if (soloRow == -1) return false;

var soloCol = UniquenessHelper.SearchExceptionInUnit(Unit.Column, 2, positions);
if (soloCol == -1) return false;

var soloMini = UniquenessHelper.SearchExceptionInUnit(Unit.MiniGrid, 2, positions);
if (soloMini == -1) return false;

for (int i = 0; i < asArray.Length - 2; i++)
var miniRow = soloMini / 3;
var miniCol = soloCol / 3;

if (soloRow / 3 == miniRow && soloCol / 3 == miniCol)
{
for (int j = i + 1; j < asArray.Length - 1; j++)
{
for (int k = j + 1; j < asArray.Length; j++)
{
var one = asArray[i];
var two = asArray[j];
var three = asArray[k];

var possibilities = Possibilities.NewEmpty();
possibilities.Add(one.One);
possibilities.Add(one.Two);
possibilities.Add(two.One);
possibilities.Add(two.Two);
possibilities.Add(three.One);
possibilities.Add(three.Two);

if(possibilities.Count != 3) continue;

var or = biValueMap[one].Or(biValueMap[two].Or(biValueMap[three]));
if (or.Count < 5) continue;

var soloRow = UniquenessHelper.SearchExceptionInUnit(Unit.Row,
UniquenessHelper.ComputeExpectedCount(Unit.Row, biValueMap[one], biValueMap[two], biValueMap[three]), or);
if (soloRow == -1) continue;

var soloCol = UniquenessHelper.SearchExceptionInUnit(Unit.Column,
UniquenessHelper.ComputeExpectedCount(Unit.Column, biValueMap[one], biValueMap[two], biValueMap[three]), or);
if (soloCol == -1) continue;

var soloMini = UniquenessHelper.SearchExceptionInUnit(Unit.MiniGrid,
UniquenessHelper.ComputeExpectedCount(Unit.MiniGrid, biValueMap[one], biValueMap[two], biValueMap[three]), or);
if (soloMini == -1) continue;

var miniRow = soloMini / 3;
var miniCol = soloCol / 3;

if (soloRow / 3 == miniRow && soloCol / 3 == miniCol)
{
foreach (var p in possibilities)
{
strategyManager.ChangeBuffer.ProposePossibilityRemoval(p, soloRow, soloCol);
}
}

if (strategyManager.ChangeBuffer.NotEmpty() && strategyManager.ChangeBuffer.Commit(this,
new BUGLiteReportBuilder(or, soloRow, soloCol)))
{
if(OnCommitBehavior == OnCommitBehavior.Return) return;
}
}
}
strategyManager.ChangeBuffer.ProposePossibilityRemoval(bi.One, soloRow, soloCol);
strategyManager.ChangeBuffer.ProposePossibilityRemoval(bi.Two, soloRow, soloCol);
}

return strategyManager.ChangeBuffer.NotEmpty() && strategyManager.ChangeBuffer.Commit(this,
new BUGLiteReportBuilder(positions, soloRow, soloCol)) && OnCommitBehavior == OnCommitBehavior.Return;
}
}

public class BUGLiteReportBuilder : IChangeReportBuilder
{
private readonly GridPositions _gp;
private readonly IEnumerable<Cell> _gp;
private readonly int _row;
private readonly int _col;

public BUGLiteReportBuilder(GridPositions gp, int row, int col)
public BUGLiteReportBuilder(IEnumerable<Cell> gp, int row, int col)
{
_gp = gp;
_row = row;
Expand Down
93 changes: 93 additions & 0 deletions Model/Solver/Strategies/ComplexBUGLiteStrategy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using Global;
using Model.Solver.StrategiesUtility;

namespace Model.Solver.Strategies;

public class ComplexBUGLiteStrategy : AbstractStrategy
{
public const string OfficialName = "BUG-Lite";
private const OnCommitBehavior DefaultBehavior = OnCommitBehavior.Return;

public override OnCommitBehavior DefaultOnCommitBehavior => DefaultBehavior;

public ComplexBUGLiteStrategy() : base(OfficialName, StrategyDifficulty.Extreme, DefaultBehavior) { }

public override void Apply(IStrategyManager strategyManager)
{
var biValueMap = GetBiValueMap(strategyManager);

foreach (var entry in biValueMap)
{
var list = entry.Value;
if (list.Count < 2) continue;

for (int i = 0; i < list.Count - 1; i++)
{
for (int j = i + 1; j < list.Count; j++)
{
var one = list[i];
var two = list[j];

var sharedUnits = new SharedUnits(one);
sharedUnits.Share(two);
if (sharedUnits.Count != 2) continue;

if (Search(strategyManager, new BiValueBlock(entry.Key, sharedUnits, one, two))) return;
}
}
}
}

private bool Search(IStrategyManager strategyManager, BiValueBlock start)
{
return false;
}

private Dictionary<BiValue, List<Cell>> GetBiValueMap(IStrategyManager strategyManager)
{
Dictionary<BiValue, List<Cell>> biValueMap = new();
for (int row = 0; row < 9; row++)
{
for (int col = 0; col < 9; col++)
{
var poss = strategyManager.PossibilitiesAt(row, col);
if (poss.Count != 2) continue;

var i = 0;
poss.Next(ref i);
var first = i;
poss.Next(ref i);
var second = i;
var bi = new BiValue(first, second);

if (!biValueMap.TryGetValue(bi, out var list))
{
list = new List<Cell>();
biValueMap[bi] = list;
}

list.Add(new Cell(row, col));
}
}

return biValueMap;
}
}

public class BiValueBlock
{
public BiValueBlock(BiValue biValue, SharedUnits sharedUnits, params Cell[] cells)
{
if (cells.Length != 2) throw new ArgumentException("Has to be 2 cells");

BiValue = biValue;
SharedUnits = sharedUnits;
Cells = cells;
}

public BiValue BiValue { get; }
public SharedUnits SharedUnits { get; }
public Cell[] Cells { get; }
}
3 changes: 0 additions & 3 deletions Model/Solver/Strategies/ReverseBUGStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

namespace Model.Solver.Strategies;

/// <summary>
/// http://forum.enjoysudoku.com/the-reverse-bug-t4431.html
/// </summary>
public class ReverseBUGStrategy : AbstractStrategy
{
public const string OfficialName = "Reverse BUG";
Expand Down
Loading

0 comments on commit 6941580

Please sign in to comment.