/// <summary> /// Initializes an instance with the specified information. /// </summary> /// <param name="conclusions">All conclusions.</param> /// <param name="views">All views.</param> /// <param name="exocet">The exocet.</param> /// <param name="digits">All digits.</param> /// <param name="endoTargetCell">The endo target cell.</param> /// <param name="targetEliminations">The target eliminations.</param> /// <param name="trueBaseEliminations">The true base eliminations.</param> /// <param name="mirrorEliminations">The mirror eliminations.</param> /// <param name="compatibilityEliminations">The compatibility eliminations.</param> public SeniorExocetTechniqueInfo( IReadOnlyList <Conclusion> conclusions, IReadOnlyList <View> views, Exocet exocet, IEnumerable <int> digits, int endoTargetCell, TargetEliminations targetEliminations, TrueBaseEliminations trueBaseEliminations, MirrorEliminations mirrorEliminations, CompatibilityTestEliminations compatibilityEliminations) : base( conclusions, views, exocet, digits, TechniqueCode.Se, null, null, targetEliminations, mirrorEliminations, default, default, default, trueBaseEliminations, compatibilityEliminations) =>
/// <summary> /// Initializes an instance with the specified information. /// </summary> /// <param name="conclusions">All conclusions.</param> /// <param name="views">All views.</param> /// <param name="exocet">The exocet.</param> /// <param name="digits">All digits.</param> /// <param name="lockedMemberQ">The locked member Q.</param> /// <param name="lockedMemberR">The locked member R.</param> /// <param name="targetEliminations">The target eliminations.</param> /// <param name="mirrorEliminations">The mirror eliminations.</param> /// <param name="bibiEliminations">The Bi-bi pattern eliminations.</param> /// <param name="targetPairEliminations">The target pair eliminations.</param> /// <param name="swordfishEliminations">The swordfish pattern eliminations.</param> public JuniorExocetTechniqueInfo( IReadOnlyList <Conclusion> conclusions, IReadOnlyList <View> views, Exocet exocet, IEnumerable <int> digits, IEnumerable <int>?lockedMemberQ, IEnumerable <int>?lockedMemberR, TargetEliminations targetEliminations, MirrorEliminations mirrorEliminations, BibiPatternEliminations bibiEliminations, TargetPairEliminations targetPairEliminations, SwordfishEliminations swordfishEliminations) : base( conclusions, views, exocet, digits, TechniqueCode.Je, lockedMemberQ, lockedMemberR, targetEliminations, mirrorEliminations, bibiEliminations, targetPairEliminations, swordfishEliminations, default, default) { }
/// <summary> /// Initializes an instance with the specified information. /// </summary> /// <param name="conclusions">All conclusions.</param> /// <param name="views">All views.</param> /// <param name="exocet">The exocet.</param> /// <param name="digits">All digits.</param> /// <param name="techniqueCode">The technique code.</param> /// <param name="lockedMemberQ">The locked member Q.</param> /// <param name="lockedMemberR">The locked member R.</param> /// <param name="targetEliminations">The target eliminations.</param> /// <param name="mirrorEliminations">The mirror eliminations.</param> /// <param name="bibiEliminations"> /// The Bi-bi pattern eliminations (only used for junior exocets). /// </param> /// <param name="targetPairEliminations"> /// The target pair eliminations (only used for junior exocets). /// </param> /// <param name="swordfishEliminations"> /// The swordfish pattern eliminations (only used for junior exocets). /// </param> /// <param name="trueBaseEliminations"> /// The true base eliminations (only used for senior exocets). /// </param> /// <param name="compatibilityEliminations"> /// The compatibility test eliminations (only used for senior exocets). /// </param> public ExocetTechniqueInfo( IReadOnlyList <Conclusion> conclusions, IReadOnlyList <View> views, Exocet exocet, IEnumerable <int> digits, TechniqueCode techniqueCode, IEnumerable <int>?lockedMemberQ, IEnumerable <int>?lockedMemberR, TargetEliminations targetEliminations, MirrorEliminations mirrorEliminations, BibiPatternEliminations bibiEliminations, TargetPairEliminations targetPairEliminations, SwordfishEliminations swordfishEliminations, TrueBaseEliminations trueBaseEliminations, CompatibilityTestEliminations compatibilityEliminations) : base(conclusions, views) { (Exocet, Digits, TechniqueCode, LockedMemberQ, LockedMemberR) = (exocet, digits, techniqueCode, lockedMemberQ, lockedMemberR); var list = (List <Conclusion>)Conclusions; if (!((TargetEliminations = targetEliminations).Conclusions is null)) { list.AddRange(TargetEliminations); } if (!((MirrorEliminations = mirrorEliminations).Conclusions is null)) { list.AddRange(MirrorEliminations); } if (!((BibiEliminations = bibiEliminations).Conclusions is null)) { list.AddRange(BibiEliminations); } if (!((TargetPairEliminations = targetPairEliminations).Conclusions is null)) { list.AddRange(TargetPairEliminations); } if (!((SwordfishEliminations = swordfishEliminations).Conclusions is null)) { list.AddRange(SwordfishEliminations); } if (!((TrueBaseEliminations = trueBaseEliminations).Conclusions is null)) { list.AddRange(TrueBaseEliminations); } if (!((CompatibilityTestEliminations = compatibilityEliminations).Conclusions is null)) { list.AddRange(CompatibilityTestEliminations); } var temp = Conclusions.Distinct().ToList(); // Call 'ToList' to execute the query forcedly. list.Clear(); list.AddRange(temp); }
/// <inheritdoc/> public override void GetAll(IBag <TechniqueInfo> accumulator, IReadOnlyGrid grid) { var compatibleCellsPlayground = (Span <int>) stackalloc int[4]; var cover = (Span <int>) stackalloc int[8]; foreach (var exocet in Exocets) { var(baseMap, targetMap, _) = exocet; var(b1, b2, tq1, tq2, tr1, tr2, s, mq1, mq2, mr1, mr2) = exocet; if (grid.GetCandidatesReversal(b1).CountSet() < 2 || grid.GetCandidatesReversal(b2).CountSet() < 2) { continue; } var baseCellsMap = new GridMap { b1, b2 }; bool isRow = baseCellsMap.CoveredLine < 18; var tempCrosslineMap = new GridMap(s) { tq1, tq2, tr1, tr2 }; short baseCandidatesMask = (short)(grid.GetCandidatesReversal(b1) | grid.GetCandidatesReversal(b2)); int i = 0; int r = GetRegion(b1, RegionLabel.Row) - 9, c = GetRegion(b1, RegionLabel.Column) - 18; foreach (int pos in ((short)(511 & ~(1 << (isRow ? r : c)))).GetAllSets()) { cover[i++] = isRow ? pos : pos + 9; } i = 0; var temp = default(GridMap); foreach (int digit in baseCandidatesMask.GetAllSets()) { if (i++ == 0) { temp = ValueMaps[digit]; } else { temp |= ValueMaps[digit]; } } temp &= tempCrosslineMap; var tempTarget = new List <int>(); for (i = 0; i < 8; i++) { var check = temp & RegionMaps[cover[i] + 9]; if (check.Count != 1) { continue; } tempTarget.Add(check.SetAt(0)); } if (tempTarget.Count == 0) { continue; } int borT = isRow ? b1 / 9 / 3 : b1 % 9 / 3; // Base or target (B or T). foreach (int[] combination in GetCombinationsOfArray(tempTarget.ToArray(), 2)) { if (isRow ? combination[0] / 9 / 3 == borT && combination[1] / 9 / 3 == borT : combination[0] % 9 / 3 == borT && combination[1] % 9 / 3 == borT) { continue; } int row1 = GetRegion(combination[0], RegionLabel.Row); int column1 = GetRegion(combination[0], RegionLabel.Column); int row2 = GetRegion(combination[1], RegionLabel.Row); int column2 = GetRegion(combination[1], RegionLabel.Column); if (isRow ? column1 == column2 : row1 == row2) { continue; } short elimDigits = (short)(( grid.GetCandidatesReversal(combination[0]) | grid.GetCandidatesReversal(combination[1])) & ~baseCandidatesMask); if (!CheckCrossline( /*baseCellsMap, */ tempCrosslineMap, ValueMaps, baseCandidatesMask, combination[0], combination[1], isRow, out int extraRegionsMask)) { continue; } var targetElims = new TargetEliminations(); short cands = (short)(elimDigits & grid.GetCandidatesReversal(combination[0])); if (cands != 0) { foreach (int digit in cands.GetAllSets()) { targetElims.Add(new Conclusion(Elimination, combination[0], digit)); } } cands = (short)(elimDigits & grid.GetCandidatesReversal(combination[1])); if (cands != 0) { foreach (int digit in cands.GetAllSets()) { targetElims.Add(new Conclusion(Elimination, combination[1], digit)); } } short tbCands = 0; for (int j = 0; j < 2; j++) { if (grid.GetCandidatesReversal(combination[j]).CountSet() == 1) { tbCands |= grid.GetCandidatesReversal(combination[j]); } } var trueBaseElims = new TrueBaseEliminations(); if (tbCands != 0 && (grid.GetStatus(combination[0]) != Empty || grid.GetStatus(combination[1]) != Empty)) { for (int j = 0; j < 2; j++) { if (grid.GetStatus(combination[j]) != Empty) { continue; } if ((cands = (short)(grid.GetCandidatesReversal(combination[j]) & tbCands)) == 0) { continue; } foreach (int digit in cands.GetAllSets()) { trueBaseElims.Add(new Conclusion(Elimination, combination[j], digit)); } } } if (tbCands != 0) { foreach (int digit in tbCands.GetAllSets()) { var elimMap = (baseCellsMap & CandMaps[digit]).PeerIntersection & CandMaps[digit]; if (elimMap.IsEmpty) { continue; } foreach (int cell in elimMap) { trueBaseElims.Add(new Conclusion(Elimination, cell, digit)); } } } var mirrorElims = new MirrorEliminations(); var compatibilityElims = new CompatibilityTestEliminations(); int target = -1; var mir = default(GridMap); var cellOffsets = new List <(int, int)> { (0, b1), (0, b2) }; foreach (int cell in tempCrosslineMap) { cellOffsets.Add((cell == combination[0] || cell == combination[1] ? 1 : 2, cell)); } var candidateOffsets = new List <(int, int)>(); if (_checkAdvanced) { for (int k = 0; k < 2; k++) { if (combination[k] == tq1 && (baseCandidatesMask & grid.GetCandidatesReversal(tr2)) == 0) { target = combination[k]; mir = mq1; } if (combination[k] == tq2 && (baseCandidatesMask & grid.GetCandidatesReversal(tr1)) == 0) { target = combination[k]; mir = mq2; } if (combination[k] == tr1 && (baseCandidatesMask & grid.GetCandidatesReversal(tq2)) == 0) { target = combination[k]; mir = mr1; } if (combination[k] == tr2 && (baseCandidatesMask & grid.GetCandidatesReversal(tq1)) == 0) { target = combination[k]; mir = mr2; } } if (target != -1) { var(tempTargetElims, tempMirrorElims) = CheckMirror( grid, target, combination[target == combination[0] ? 1 : 0], 0, baseCandidatesMask, mir, 0, -1, cellOffsets, candidateOffsets); targetElims = TargetEliminations.MergeAll(targetElims, tempTargetElims); mirrorElims = MirrorEliminations.MergeAll(mirrorElims, tempMirrorElims); } short incompatible = CompatibilityTest( baseCandidatesMask, ValueMaps, tempCrosslineMap, baseCellsMap, combination[0], combination[1]); if (incompatible != 0) { compatibleCellsPlayground[0] = b1; compatibleCellsPlayground[1] = b2; compatibleCellsPlayground[2] = combination[0]; compatibleCellsPlayground[3] = combination[1]; for (int k = 0; k < 4; k++) { cands = (short)(incompatible & grid.GetCandidatesReversal(compatibleCellsPlayground[k])); if (cands == 0) { continue; } foreach (int digit in cands.GetAllSets()) { compatibilityElims.Add( new Conclusion(Elimination, compatibleCellsPlayground[k], digit)); } } } CompatibilityTest2( grid, ref compatibilityElims, baseCellsMap, baseCandidatesMask, combination[0], combination[1]); } if (_checkAdvanced ? mirrorElims.Count == 0 && compatibilityElims.Count == 0 && targetElims.Count == 0 && trueBaseElims.Count == 0 : mirrorElims.Count == 0 && compatibilityElims.Count == 0) { continue; } int endoTargetCell = combination[s[combination[0]] ? 0 : 1]; short m1 = grid.GetCandidatesReversal(b1); short m2 = grid.GetCandidatesReversal(b2); short m = (short)(m1 | m2); foreach (int digit in m1.GetAllSets()) { candidateOffsets.Add((0, b1 * 9 + digit)); } foreach (int digit in m2.GetAllSets()) { candidateOffsets.Add((0, b2 * 9 + digit)); } // Record extra region cells (mutant exocets). foreach (int region in extraRegionsMask.GetAllSets()) { foreach (int cell in RegionCells[region]) { if (tempCrosslineMap[cell] || b1 == cell || b2 == cell) { continue; } cellOffsets.Add((2, cell)); } } accumulator.Add( new SeniorExocetTechniqueInfo( conclusions: new List <Conclusion>(), views: new[] { new View( cellOffsets, candidateOffsets, regionOffsets: null, links: null) }, exocet, digits: m.GetAllSets(), endoTargetCell, targetEliminations: targetElims, trueBaseEliminations: trueBaseElims, mirrorEliminations: mirrorElims, compatibilityEliminations: compatibilityElims)); } } }