/// <summary>
        /// Fills an existing <see cref="SudokuPuzzle"/> with numbers.
        /// </summary>
        /// <param name="sudoku">The puzzle to fill with numbers.</param>
        /// <exception cref="ArgumentNullException"><c><paramref name="sudoku"/></c> is <c>null</c>.</exception>
        public static void AddNumbers(SudokuPuzzle sudoku)
        {
            if (sudoku is null)
            {
                throw new ArgumentNullException(nameof(sudoku));
            }

            sudoku.DisablePossible = true;
            SudokuSolver.RecursiveSolve(sudoku);
            sudoku.DisablePossible = false;
            sudoku.ResetPossible();
            sudoku.ClearReadOnlyProperties();
            sudoku.SetSolutions();
        }
        /// <summary>
        /// Removes numbers from an existing <see cref="SudokuPuzzle"/> according to its difficulty.
        /// </summary>
        /// <param name="sudoku">The <see cref="SudokuPuzzle"/> to remove numbers from.</param>
        /// <exception cref="ArgumentNullException"><c><paramref name="sudoku"/></c> is <c>null</c>.</exception>
        public static void RemoveNumbers(SudokuPuzzle sudoku)
        {
            if (sudoku is null)
            {
                throw new ArgumentNullException(nameof(sudoku));
            }

            sudoku.ClearReadOnlyProperties();
            int attempts = 45;

            switch (sudoku.Difficulty)
            {
            case SudokuDifficulty.Medium:
                attempts = 60;
                break;

            case SudokuDifficulty.Hard:
                attempts = 75;
                break;
            }

            do
            {
                int row, column;

                do
                {
                    row    = SudokuGenerator.Random.Next(sudoku.Size);
                    column = SudokuGenerator.Random.Next(sudoku.Size);
                } while (sudoku[row, column] == 0);

                int value = sudoku[row, column];
                sudoku[row, column] = 0;
                bool solvable = SudokuSolver.CheckSolvable(sudoku, out bool multipleSolutions);

                if (!solvable || multipleSolutions)
                {
                    sudoku[row, column] = value;
                }
            } while (attempts-- > 0);

            sudoku.SetReadOnlyProperties();
        }