Example #1
0
        private static void SearchForSingleInGroup(SolvingContext context, ICellGroup group)
        {
            var allNumbers = Enumerable.Range(1, 9)
                             .Select(x => (short)x)
                             .Except(group.Select(x => x.Value).Distinct())
                             .ToList();

            var singles = allNumbers.Select(x => new
            {
                Value = x,
                ElligibleCellsCount = group.Count(y => y.CanPutCandidate(x))
            })
                          .Where(x => x.ElligibleCellsCount == 1)
                          .Select(x => x.Value)
                          .ToList();

            var single = singles.FirstOrDefault();

            if (single == 0)
            {
                return;
            }

            var targetCell = group.FirstOrDefault(x => x.CanPutCandidate(single));

            if (targetCell == null)
            {
                return;
            }
            var newCell = new Cell(single, targetCell.X, targetCell.Y);

            context.Grid = context.Grid.UpdateCell(newCell);
            context.FilledInCellsCount++;
            context.GoToLoopStart = true;
        }
Example #2
0
        private static void FindCandidatesPairsInCells(SolvingContext context, ICellGroup cellGroup)
        {
            var allNumbers             = GetAllSudokuNumbers();
            var unassignedValues       = allNumbers.Except(cellGroup.Select(x => x.Value)).ToList();
            var allNumbersCombinations = unassignedValues
                                         .SelectMany(x => unassignedValues, Tuple.Create)
                                         .Where(tuple => tuple.Item1 != tuple.Item2)
                                         .ToList();

            foreach (var combination in allNumbersCombinations)
            {
                var first           = combination.Item1;
                var firstValueCells = cellGroup.Where(x => x.CanPutCandidate(first)).ToList();

                var second           = combination.Item2;
                var secondValueCells = cellGroup.Where(x => x.CanPutCandidate(second)).ToList();

                if (firstValueCells.Count != 2 || secondValueCells.Count != 2 ||
                    !firstValueCells.SequenceEqual(secondValueCells))
                {
                    continue;
                }

                foreach (var cell in firstValueCells)
                {
                    context.CellsAffectedWithCrossOut += cell.RemoveCandidatesExcept(combination.ToArray());
                }

                RemoveCandidates(context, cellGroup, Tuple.Create(firstValueCells.First(), firstValueCells.Last()));
            }
        }
Example #3
0
 private void RememberValueIsNowInvalidForTheRestOfTheCellsOfMy(ICellGroup cellgroup, CellValue value)
 {
     foreach (var cell in cellgroup.Cells.Where(cell => cell != this))
     {
         cell.RememberValueCanNotBe(value);
     }
 }
        /// <summary>
        /// Checks if an enumeration of <see cref="ICell"/> contains one cell for each value starting at 1
        /// </summary>
        /// <param name="line"> The enumeration of cells </param>
        /// <returns> True if the group is completed </returns>
        public static bool IsCompleted(this ICellGroup line)
        {
            for (int column = 0; column < line.Cells.Count(); column++)
            {
                if (!line.Cells.Any(x => x.Value == column + 1))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #5
0
        private static void RemoveCandidates(SolvingContext context, ICellGroup cellGroup,
                                             Tuple <ICell, ICell> pair)
        {
            var otherCells  = cellGroup.Except(pair.ToList()).ToList();
            var firstFields = pair.Item1.GetCandidates().ToList();

            context.Pairs.Add(Tuple.Create(firstFields.First(), firstFields.Last()));
            context.PairFound = true;
            foreach (var otherCell in otherCells)
            {
                context.CellsAffectedWithCrossOut += otherCell.RemoveCandidates(firstFields.ToArray());
            }
        }
        /// <summary>
        /// Get the indices of all empty cells inside this line
        /// </summary>
        /// <param name="cells"> The enumeration of cells </param>
        /// <returns> The indices of the empty cells </returns>
        public static IEnumerable <uint> GetEmptyIndices(this ICellGroup line)
        {
            var rVal = new LinkedList <uint>();

            for (uint i = 0; i < line.Cells.Count(); i++)
            {
                if (line.Cells.ElementAt((int)i).Value == 0)
                {
                    rVal.AddLast(i);
                }
            }

            return(rVal);
        }
        /// <summary>
        /// Get all the values that are missing in an enumeration of cells.
        /// </summary>
        /// <returns> An enumeration of uints representing the missing values </returns>
        public static IEnumerable <uint> GetMissingValues(this ICellGroup line)
        {
            var rVal = new LinkedList <uint>();

            for (uint i = 1; i <= line.Cells.Count(); i++)
            {
                if (!line.Cells.Any(x => x.Value == i))
                {
                    rVal.AddLast(i);
                }
            }

            return(rVal);
        }
Example #8
0
        private static IEnumerable <Tuple <ICell, ICell> > HandleCellPairs(SolvingContext context,
                                                                           IEnumerable <Tuple <ICell, ICell> > combinations, ICellGroup cellGroup)
        {
            foreach (var combination in combinations)
            {
                if (combination.Item1 == null || combination.Item2 == null)
                {
                    break;
                }

                var firstFields  = combination.Item1.GetCandidates().ToList();
                var secondFields = combination.Item2.GetCandidates().ToList();
                if (firstFields.Count != 2 || secondFields.Count != 2 ||
                    !firstFields.SequenceEqual(secondFields))
                {
                    continue;
                }

                RemoveCandidates(context, cellGroup, combination);

                yield return(combination);
            }
        }
 /// <summary>
 /// Checks if an <see cref="ICellGroup"/> contains a specific number
 /// </summary>
 /// <param name="number">The number to look for </param>
 /// <returns> True if the group contains the number </returns>
 public static bool Contains(this ICellGroup line, uint number)
 {
     return(line.Cells.Any(x => x.Value == number));
 }