def reduce_puzzle(values):
    "Reduce a Sudoku puzzle by repeatedly applying all constraint strategies\n\n    Parameters\n    ----------\n    values(dict)\n        a dictionary of the form {'box_name': '123456789', ...}\n\n    Returns\n    -------\n    dict or False\n        The values dictionary after continued application of the constraint strategies\n        no longer produces any changes, or False if the puzzle is unsolvable \n    "
    solved_values = [box for box in values.keys() if (len(values[box]) == 1)]
    stalled = False
    while (not stalled):
        solved_values_before = len([box for box in values.keys() if (len(values[box]) == 1)])
        values = eliminate(values)
        values = only_choice(values)
        values = naked_twins(values)
        solved_values_after = len([box for box in values.keys() if (len(values[box]) == 1)])
        stalled = (solved_values_before == solved_values_after)
        if len([box for box in values.keys() if (len(values[box]) == 0)]):
            return False
    return values
Reduce a Sudoku puzzle by repeatedly applying all constraint strategies

Parameters
----------
values(dict)
    a dictionary of the form {'box_name': '123456789', ...}

Returns
-------
dict or False
    The values dictionary after continued application of the constraint strategies
    no longer produces any changes, or False if the puzzle is unsolvable
def reduce_puzzle(values):
    "Reduce a Sudoku puzzle by repeatedly applying all constraint strategies\n\n    Parameters\n    ----------\n    values(dict)\n        a dictionary of the form {'box_name': '123456789', ...}\n\n    Returns\n    -------\n    dict or False\n        The values dictionary after continued application of the constraint strategies\n        no longer produces any changes, or False if the puzzle is unsolvable \n    "
    solved_values = [box for box in values.keys() if (len(values[box]) == 1)]
    stalled = False
    while (not stalled):
        solved_values_before = len([box for box in values.keys() if (len(values[box]) == 1)])
        values = eliminate(values)
        values = only_choice(values)
        values = naked_twins(values)
        solved_values_after = len([box for box in values.keys() if (len(values[box]) == 1)])
        stalled = (solved_values_before == solved_values_after)
        if len([box for box in values.keys() if (len(values[box]) == 0)]):
            return False
    return values