def problem_8_8(num_queens):
    """ Write an algorithm to print all ways of arranging eight queens on a
    chess board so that none of them share the same row, column or diagonal.

    Solution: use recursive backtracking to compute all combinations.
    """
    def expand_solution(solution, num):
        """ Expands the current solution by adding another queen.
        Only produces valid partial solutions.
        """
        taken_columns = set([c for c in solution])
        taken_first_diagonals = set([i+j for (i, j) in enumerate(solution)])
        taken_second_diagonals = set([j-i for (i, j) in enumerate(solution)])
        i = len(solution)

        candidates = []
        for j in range(num):
            if j in taken_columns or \
               i+j in taken_first_diagonals or \
               j-i in taken_second_diagonals:
                continue
            tmp = solution[:]
            tmp.append(j)
            candidates.append(tmp)
        return candidates

    def recurse(partial_solution, size):
        if len(partial_solution) == size:
            return [partial_solution]

        solutions = []
        for candidate in expand_solution(partial_solution, size):
            solutions.extend(recurse(candidate, size))
        return solutions

    return recurse([], num_queens)