public void Init()
        {
            maze      = new Maze(mazeWidth, mazeHeight);
            rng       = new Random(1001);
            generator = new PrimsAlgorithm(rng);
            generator.Generate(maze);

            solver = new RecursiveSolver(maze);
        }
Пример #2
0
        static void BashThroughSudokus(string path, int number, int start = 0)
        {
            Shape shape = Shape.SquareGrid(3);

            string [] lines = File.ReadAllLines(path);

            ISolver    solver = new RecursiveSolver();
            SolverArgs args   = new SolverArgs()
            {
                use_set_elimination = false
            };

            Stopwatch stopwatch = Stopwatch.StartNew();

            for (int i = start; i < number + start; i++)
            {
                int [] grid = lines [i].Select(x => int.Parse(x.ToString())).ToArray();

                int [] [] solution = solver.Solve(shape, grid, args, out int diff, out int [] [] fill_orders);

                if (solution.Length != 1)
                {
                    Console.WriteLine("!");
                }

                if ((i + 1) % 100 == 0)
                {
                    Console.Write(".");
                }
                if ((i + 1) % 500 == 0)
                {
                    Console.Write(" ");
                }
                if ((i + 1) % 1000 == 0)
                {
                    Console.Write("\n");
                }
                if ((i + 1) % 5000 == 0)
                {
                    Console.Write("\n");
                }
            }

            double n = stopwatch.Elapsed.TotalSeconds / number;

            Console.WriteLine("\n" + n * 1000 + "ms per sudoku.");
            Console.WriteLine(1 / n + " sudoku per second.");
        }
    public static void Main(string[] args)
    {
        int limit         = 20000;
        int numIterations = 1000;

        var recursiveSolver = new RecursiveSolver();
        var iterativeSolver = new IterativeSolver();

        Console.Write("Testing iterative approach... ");
        GetAverageResults(numIterations, limit, iterativeSolver);

        Console.Write("Testing recursive approach... ");
        GetAverageResults(numIterations, limit, recursiveSolver);

        Console.WriteLine("Complete!");
        Console.ReadKey();
    }
Пример #4
0
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // Get a CurrencyHolder holding notations made from dataGrid data in notationsList
            var holder = new CurrencyHolder(notationsList.Select(f => f.GetNotation()).ToList());
            var value  = inputTextBox.Text;

            IChangeRounder rounder = null;

            if (NoroundRadioButton.IsChecked.GetValueOrDefault(false))
            {
                rounder = new NoRounding();
            }
            if (NaiveroundingRadioButton.IsChecked.GetValueOrDefault(false))
            {
                rounder = new NaiveRounder();
            }

            IChangeSolver solver = null;

            if (recursiveRadioButton.IsChecked.GetValueOrDefault(false))
            {
                solver = new RecursiveSolver(rounder);
            }
            if (iterativeRadioButton.IsChecked.GetValueOrDefault(false))
            {
                solver = new IterativeSolver(rounder);
            }

            if (solver != null && decimal.TryParse(value, out decimal amount))
            {
                solver.FindReturnFor(holder, amount);

                // Update dataGrid with result
                notationsList.ForEach(f => f.Update());
                dataGrid.Items.Refresh();

                changeLabel.Content = $"Amount left: {amount - holder.SumTaken()}";
            }
            else
            {
                changeLabel.Content = "Input is not a valid number";
                inputTextBox.Text   = "111.55";
            }
        }
Пример #5
0
        static void SolveSome3x3Puzzle()
        {
            // Solve something
            Shape shape3x3 = Shape.SquareGrid(3);

            int [] clues = RecursiveSolver.Get3x3Grid(base_path + @"3x3 Puzzles\hard.txt");

            int [] [] solutions = new RecursiveSolver().Solve(shape3x3, clues, new SolverArgs()
            {
                max_solutions = 2
            }, out int difficulty, out int [] [] cell_orders);

            shape3x3.Print(clues);

            Console.WriteLine(difficulty);

            foreach (int [] sol in solutions)
            {
                shape3x3.Print(sol);
            }
        }
Пример #6
0
        private void MakeNonograms(bool createHandlers)
        {
            DrawDelayed(() => _solvedNonogram, 0, true);

            DrawDelayed(() =>
            {
                var clone = _solvedNonogram.Clone() as Nonogram;
                clone.Clear();
                var solver = new ContradictionSolver();
                solver.Solve(clone);
                return(clone);
            }, 1, createHandlers);

            DrawDelayed(() =>
            {
                var clone  = _solvedNonogram.Clone() as Nonogram;
                var solver = new ContradictionSolver();
                solver.SolveWithOneGuess(clone);
                return(clone);
            }, 2, createHandlers);


            DrawDelayed(() =>
            {
                var clone  = _solvedNonogram.Clone() as Nonogram;
                var solver = new ArcConsistencySolver();
                solver.Solve(clone);
                return(clone);
            }, 3, createHandlers);

            DrawDelayed(() =>
            {
                var clone  = _solvedNonogram.Clone() as Nonogram;
                var solver = new RecursiveSolver();
                solver.Solve(clone);
                return(clone);
            }, 4, createHandlers);
        }
Пример #7
0
        static void Main(string[] args)
        {
            Console.CursorVisible = false;
            r       = new Random((int)DateTime.Now.Ticks);
            maze    = new Maze(mazeWidth, mazeHeight);
            display = new char[mazeWidth * offset, mazeHeight *offset];

            Console.WriteLine("Choose a type of maze to generate:\n");
            Console.WriteLine("1: Recursive Backtracker");
            Console.WriteLine("2: Randomised Prim's Algorithm");
            var mazeOption = Console.ReadKey().Key;

            IMazeGenerator generator;

            switch (mazeOption)
            {
            case ConsoleKey.D2:
                generator = new PrimsAlgorithm(r);
                break;

            case ConsoleKey.D1:
            default:
                generator = new RecursiveBacktracker(r);
                break;
            }
            Console.Clear();

            Console.WriteLine("Choose a type of solver, if any:\n");
            Console.WriteLine("0: No solver");
            Console.WriteLine("1: Recursive Solver");
            Console.Write("2: A* Solver");
            var solverOption = Console.ReadKey().Key;

            ISolver solver;

            switch (solverOption)
            {
            case ConsoleKey.D1:
                solver = new RecursiveSolver(maze);
                break;

            case ConsoleKey.D2:
                solver = new AStar(maze);
                break;

            default:
                solver = null;
                break;
            }

            while (true)
            {
                maze.InitialiseNodes();
                generator.Generate(maze);
                Console.Clear();

                for (int h = 0; h < mazeHeight; h++)
                {
                    for (int w = 0; w < mazeWidth; w++)
                    {
                        WriteNodeChar(w, h, maze[(uint)w, (uint)h].Walls);
                    }
                }

                if (solver != null)
                {
                    Random  r          = new Random();
                    NodePtr startPoint = new NodePtr((uint)maze.Width + 1, (uint)maze.Height + 1); // Purposefully not valid
                    NodePtr endPoint   = new NodePtr((uint)maze.Width + 1, (uint)maze.Height + 1);
                    while (true)
                    {
                        //TODO: Probably refactor
                        var startPointIsValid = maze.IsPointValid(startPoint);
                        var endPointIsValid   = maze.IsPointValid(endPoint);
                        if (startPointIsValid && endPointIsValid)
                        {
                            break;
                        }

                        if (!startPointIsValid)
                        {
                            startPoint = new NodePtr((uint)r.Next(maze.Width), (uint)r.Next(maze.Height));
                        }
                        if (!endPointIsValid)
                        {
                            endPoint = new NodePtr((uint)r.Next(maze.Width), (uint)r.Next(maze.Height));
                        }
                    }

                    var solution = solver.Solve(startPoint, endPoint);

                    if (solution != null)
                    {
                        WriteSolution(startPoint, endPoint, solution);
                        Console.WriteLine(string.Format("Solving for: Start - {0}x, {1}y; End - {2}x, {3}y",
                                                        startPoint.x, startPoint.y,
                                                        endPoint.x, endPoint.y));
                    }
                    else
                    {
                        Console.WriteLine("Cannot find a Solution.....");
                    }
                }

                DrawDisplay();
                Console.WriteLine();
                Console.WriteLine("Press any key to regenerate, or Escape to exit....");
                if (Console.ReadKey().Key == ConsoleKey.Escape)
                {
                    break;
                }
            }
        }
Пример #8
0
        public void TestCustomNotationsWithLeftover()
        {
            IChangeSolver solver = new RecursiveSolver(_rounder);

            SolverTestsCommon.TestCustomNotationsWithLeftover(solver);
        }
Пример #9
0
        public void TestComplicatedNumber()
        {
            IChangeSolver solver = new RecursiveSolver(_rounder);

            SolverTestsCommon.TestComplicatedNumber(solver);
        }
Пример #10
0
        public static int [] GeneratePuzzle(Shape shape, int [] solution, int seed = 0, int min_clues = 0)
        {
            int [] initial_board = (int [])solution.Clone();

            Random rng = new Random(seed);

            int iterations = 0;

            int best_score = 0;

            int [] best_board = null;

            try {
                RecursiveRemove(initial_board, 0, 0);
            } catch (GetMeOutOfHereException) {
                return(best_board);
            }

            throw new Exception("This code should never be executed.");

            void RecursiveRemove(int [] board, int groups_gone, int squares_gone)
            {
                int [] class_order = Utils.RandomPermutation(rng, shape.symmetry.cells_by_class.Length, 0);

                // Request that higlighted groups are removed first
                if (false && shape.highlight != null && shape.highlight.Any())
                {
                    int i = class_order.Length - 1;
                    int j = 0;

                    while (i >= j)
                    {
                        if (shape.symmetry.cells_by_class [class_order [i]]
                            .Select(x => shape.highlight [x])
                            .Any()
                            )
                        {
                            int temp = class_order [i];
                            class_order [i] = class_order [j];
                            class_order [j] = temp;

                            j += 1;
                        }
                        else
                        {
                            i -= 1;
                        }
                    }
                }

                // Console.WriteLine (string.Join (",", class_order.Select (x => x.ToString ())));

                for (int i = 0; i < class_order.Length; i++)
                {
                    // Check if this has already been removed
                    if (board [shape.symmetry.cells_by_class [class_order [i]] [0]] == 0)
                    {
                        continue;
                    }

                    // Buck out after too many iterations (so this function doesn't hang forever)
                    iterations++;

                    if (iterations > 100)
                    {
                        throw new GetMeOutOfHereException(board);
                    }

                    // Construct new board
                    int [] points = shape.symmetry.cells_by_class [class_order [i]];

                    // Check if too few clues are left
                    if (shape.num_cells - points.Length - squares_gone < min_clues)
                    {
                        continue;
                    }

                    int [] new_board = (int [])board.Clone();

                    for (int j = 0; j < points.Length; j++)
                    {
                        new_board [points [j]] = 0;
                    }

                    // Check that every letter in the alphabet appears once
                    bool [] has_been_used = new bool [shape.group_size];

                    for (int b = 0; b < shape.num_cells; b++)
                    {
                        if (new_board [b] > 0)
                        {
                            has_been_used [new_board [b] - 1] = true;
                        }
                    }

                    bool any_missing = false;
                    for (int v = 0; v < shape.group_size; v++)
                    {
                        if (!has_been_used [v])
                        {
                            any_missing = true;
                            break;
                        }
                    }

                    if (any_missing)
                    {
                        continue;
                    }

                    // Check for solutions
                    try {
                        int [] [] solutions = new RecursiveSolver().Solve(
                            shape,
                            new_board,
                            new SolverArgs()
                        {
                            max_solutions = 2, iteration_limit = 50000
                        },
                            out int diff,
                            out int [] [] cell_fill_orders
                            );

                        if (solutions.Length == 1)
                        {
                            int score = squares_gone + diff;

                            if (score > best_score)
                            {
                                best_score = score;
                                best_board = new_board;
                            }

                            RecursiveRemove(new_board, groups_gone + 1, squares_gone + points.Length);
                        }
                    } catch (RecursiveSolver.TooManyIterationsException) {
                    }
                }
            }
        }
Пример #11
0
        public int [] PopulateGrid(Shape shape, PopulatorArgs args, int [] grid = null)
        {
            // Fill in the first group
            int [] full_grid = new int [shape.num_cells];

            Random rng = new Random(args.random_seed);

            if (grid == null)
            {
                int [] perm = Utils.RandomPermutation(rng, shape.group_size);

                for (int i = 0; i < shape.group_size; i++)
                {
                    full_grid [shape.cells_by_group [0, i]] = perm [i];
                }
            }
            else
            {
                Array.Copy(grid, full_grid, grid.Length);

                for (int i = 0; i < shape.num_groups; i++)
                {
                    bool [] has_been_found = new bool [shape.group_size];

                    for (int j = 0; j < shape.group_size; j++)
                    {
                        int v = full_grid [shape.cells_by_group [i, j]];

                        if (v > 0)
                        {
                            if (has_been_found [v - 1])
                            {
                                throw new DuplicateElementInGroupException("Duplicate element in a group.", v - 1);
                            }

                            has_been_found [v - 1] = true;
                        }
                    }
                }
            }

            try {
                int [] [] solutions = new RecursiveSolver().Solve(
                    shape,
                    full_grid,
                    new SolverArgs(args)
                {
                    rng = rng, max_solutions = args.print_fixed_cells ? 10 : 1, iteration_limit = 10_000_000
                },
                    out int difficulty,
                    out int [] [] cell_fill_orders
                    );

                if (args.print_fixed_cells)
                {
                    int [] fixed_cells = (int [])solutions [0].Clone();

                    Console.WriteLine(solutions.Length);

                    for (int i = 1; i < solutions.Length; i++)
                    {
                        for (int j = 0; j < shape.num_cells; j++)
                        {
                            if (fixed_cells [j] != 0 && solutions [i] [j] != fixed_cells [j])
                            {
                                fixed_cells [j] = 0;
                            }
                        }
                    }

                    shape.Print(fixed_cells, args.alphabet);
                }

                if (solutions.Length == 0)
                {
                    throw new GridNotSolubleException("Grid could not be completed.");
                }

                return(solutions [0]);
            } catch (RecursiveSolver.TooManyIterationsException) {
Пример #12
0
        public SolveResult Solve(IProblemDefinition gridToSolve)
        {
            var iterativeSolver = new RecursiveSolver(gridToSolve.PossibilitiesSquareGrid);

            return iterativeSolver.Solve(gridToSolve.StartingKnownSquares);
        }