// Get all the possible values from key and filter them using the filter public Keys <TKey> Process(IPuzzleEngine <TKey> engine) { Keys <TKey> keysChanged = engine.Puzzle.Space.Eliminate(Keys, Filter); engine.Add(new JobSearch <TKey>("Filter", keysChanged)); return(keysChanged); }
/// <summary> /// This elimination works out if there is an intersection between mutually exclusive sets /// that contains any values that are in the intersection and not in the outersection of one set. /// If this is so, (and both sets must contain that value) then the values can be eliminated from /// the other set also. Only need - in addition to above, used when intersecting points > 1. /// </summary> static public int CreateCompleteIntersectActions(Keys <TKey> group1, Keys <TKey> group2, IPuzzleEngine <TKey> engine) { int added = 0; Keys <TKey> keysIntersection = new Keys <TKey>(group1); keysIntersection.IntersectWith(group2); if (keysIntersection.Count > 1) { Keys <TKey> keysOuter1 = new Keys <TKey>(group1); keysOuter1.ExceptWith(keysIntersection); Keys <TKey> keysOuter2 = new Keys <TKey>(group2); keysOuter2.ExceptWith(keysIntersection); IPossible valuesIntersect = engine.Puzzle.Space.AllValuesAt(keysIntersection); IPossible valuesOuter1 = engine.Puzzle.Space.AllValuesAt(keysOuter1); IPossible valuesOuter2 = engine.Puzzle.Space.AllValuesAt(keysOuter2); Possible filter2 = new Possible(valuesIntersect); filter2.FilterOut(valuesOuter1); if (filter2.Count > 0) { engine.Add(new JobFilter <TKey>("Intersection", keysOuter2, filter2)); added++; } // find each value that is present in the intersection (and not in outer1) // and eliminate it from the set2 // find each value that is present in the intersection (and not in outer) // and eliminate it from the set1 Possible filter1 = new Possible(valuesIntersect); filter1.FilterOut(valuesOuter2); if (filter1.Count > 0) { engine.Add(new JobFilter <TKey>("Intersection", keysOuter1, filter1)); added++; } } return(added); }
static public int CreateCompleteSetActions(Keys <TKey> group1, Keys <TKey> group2, IPuzzleEngine <TKey> engine) { int added = 0; // This works out possibleInner (go to space and union all values); IPossible possibleInner = engine.Puzzle.Space.AllValuesAt(group1); // If the values in the set are equal to the // available spaces in the solution then we consider this set // complete and can eliminate it from the rest of the group // (e.g. 1 value in 1 cell, or 8 values in 8 cells) if (possibleInner.Values.Count == group1.Count()) { // This finds the working group of locations (excludes the changed set) Keys <TKey> workingGroup = new Keys <TKey>(group2); workingGroup.ExceptWith(group1); IJob <TKey> job = new JobFilter <TKey>("CompleteSet", workingGroup, possibleInner); engine.Add(job); added++; // Get all the possible values from key and filter them out of the group } return(added); }
int CreateXWingProcesses(IList <IList <IKeyedRegions <TKey> > > xwings, IPuzzleEngine <TKey> engine) { int added = 0; foreach (IList <IKeyedRegions <TKey> > xwing in xwings) { foreach (Keys <TKey> keys1 in xwing[0].OtherKeys) { foreach (TKey key1 in keys1) { foreach (Keys <TKey> keys2 in xwing[1].OtherKeys) { foreach (TKey key2 in keys2) { Keys <TKey> keysA = new Keys <TKey>() { key1, key2 }; IConstraints <TKey> y = engine.Puzzle.Constraints.FindOtherConstraintsContainingAllKeys( keysA, new HashSet <ConstraintType>() { this.Type }, new Constraints <TKey>() { this }); foreach (IConstraint <TKey> constraint in y) { if (xwing[0].Value.IsSubsetOf(keysA.ReducedSetValues(constraint.Keys, engine.Puzzle.Space))) { Keys <TKey> keys1R = new Keys <TKey>(keys1); keys1R.Remove(key1); if (keys1R.Count > 0) { //SpaceAdapter<int>.ToFile(engine.Puzzle.Space.ToString(), 0); JobFilter <TKey> action1 = new JobFilter <TKey>("XWing", keys1R, xwing[0].Value); engine.Add(action1); added++; } Keys <TKey> keys2R = new Keys <TKey>(keys2); keys2R.Remove(key2); if (keys2R.Count > 0) { //SpaceAdapter<int>.ToFile(engine.Puzzle.Space.ToString(), 2); JobFilter <TKey> action2 = new JobFilter <TKey>("XWing", keys2R, xwing[1].Value); engine.Add(action2); added++; //SpaceAdapter<int>.ToFile(engine.Puzzle.Space.ToString(), 3); } } } } } } } } return(added); }