Ejemplo n.º 1
0
        public Puzzle Solve(Puzzle puzzle, SolverContext context, List <CellRange> anchors)
        {
            bool wordsInserted;

            do
            {
                wordsInserted = false;
                foreach (var range in puzzle.PartiallyFilledCellRanges.ToList())
                {
                    var words = puzzle.Words.Where(w => puzzle.Matches(range, w));
                    if (!words.Any())
                    {
                        return(null);
                    }
                    if (words.Count() == 1)
                    {
                        puzzle        = puzzle.SetWord(range, words.Single());
                        wordsInserted = true;
                    }
                }
            } while (wordsInserted);

            var part = puzzle.PartiallyFilledCellRanges.ToList();
            List <Tuple <string, CellRange> > pairs = new List <Tuple <string, CellRange> >();

            foreach (var word in puzzle.Words)
            {
                foreach (var cellRange in part.Where(p => puzzle.Matches(p, word)))
                {
                    pairs.Add(Tuple.Create(word, cellRange));
                }
            }

            foreach (var pair in OrderPairs(pairs, anchors))
            {
                var word  = pair.Item1;
                var range = pair.Item2;

                context.count++;

                var candidatePuzzle = puzzle.SetWord(range, word);
                if (candidatePuzzle == null)
                {
                    continue;
                }

                if (context.AlreadyTried(candidatePuzzle))
                {
                    continue;
                }

                //var words = candidatePuzzle.Words.ToArray();
                //var ranges = candidatePuzzle.PartiallyFilledCellRanges.Concat(candidatePuzzle.UnfilledCellRanges).ToArray();
                //if (words.Length != ranges.Length)
                //{
                //    continue;
                //}

                if (context.count % 10 == 0)
                {
                    Console.Clear();
                    Console.WriteLine(candidatePuzzle);
                    Console.WriteLine($"Solving C:{context.count} D:{context.depth} T:{context.TriedCount}");
                }
                //foreach (var anchor in anchors)
                //{
                //    var cnt = part.Where(p => p.Overlaps(anchor)).Count();
                //    Console.WriteLine($"{anchor}: {cnt}");
                //}
                //if (context.count > 50000)
                //{
                //    Console.ReadKey();
                //}
                context.depth++;
                var solved = Solve(candidatePuzzle, context, anchors.Concat(new[] { range }).ToList());
                context.depth--;
                if (solved != null)
                {
                    return(solved);
                }
                if (candidatePuzzle.IsPartialSolution())
                {
                    Console.WriteLine("Rejected partial solution:");
                    Console.WriteLine(candidatePuzzle);
                    candidatePuzzle.IsPartialSolution();
                    Environment.Exit(-1);
                }
                context.AddTried(candidatePuzzle.CopyOfCells());
            }

            // No solution is possible
            return(null);
        }