(eqparams, trace_combo=({}, 0, set(range(10))), power=0)
return None
This function recursively traces a parsed expression from lowest
       digits to highest, generating additional digits when necessary
       checking the digit sum is divisible by 10, carrying the multiple of 10
       up to the next level
This function recursively traces a parsed expression from lowest
       digits to highest, generating additional digits when necessary
       checking the digit sum is divisible by 10, carrying the multiple of 10
       up to the next level
This function recursively traces a parsed expression from lowest digits to highest generating additional digits when necessary checking the digit sum is divisible by 10 carrying the multiple of 10 up to the next level
def check_rec(eqparams, trace_combo=({}, 0, set(range(10))), power=0):
    """This function recursively traces a parsed expression from lowest
       digits to highest, generating additional digits when necessary
       checking the digit sum is divisible by 10, carrying the multiple of 10
       up to the next level
    """
    # Basic parameters of the equation,
    # maximal digit rank
    # characters with multipliers by rank
    # unique non-zero characters by rank
    # unique zero-allowed characters by rank
    # all unique characters by rank
    max_digit_rank, multipliers_chars, non_zero_chars, zero_chars, unique_chars = eqparams
    # recursion cumulative parameters
    # established characters with digits
    # carry-over from the previous level
    # remaining unassigned digits
    prev_digits, carry_over, remaining_digits = trace_combo
    # the maximal 10-power (beyond the maximal rank)
    # is reached
    if power == max_digit_rank:
        # Carry-over is zero, meaning solution is found
        if carry_over == 0:
            return prev_digits
        else:
            # Otherwise the solution in this branch is not found
            # return empty
            return {}
    digit_letters = unique_chars[power]  # all new unique letters from the current level
    part_sum = carry_over  # Carry over from lower level
    remaining_exp = []  # TBD letters
    # Break down the current level letter into what can be
    # calculated in the partial sum and remaining TBD letter-digits
    for caesar, van_gogh in multipliers_chars[power]:
        if caesar in prev_digits:
            part_sum += van_gogh * prev_digits[caesar]
        else:
            remaining_exp.append((caesar, van_gogh))
    # Generate permutations for the remaining digits and currecnt level
    # non-zero letters and zero-allowed letters
    for newdigs in dig_perms(remaining_digits, non_zero_chars[power], zero_chars[power]):
        # build the dictionary for the new letters and this level
        new_dict = dict(zip(digit_letters, newdigs))
        # complete the partial sum into test sum using the current permutation
        testsum = part_sum + sum([new_dict[caesar] * van_gogh
                                 for caesar, van_gogh in remaining_exp])
        # check if the sum is divisible by 10
        dali, rembrandt = divmod(testsum, 10)
        if rembrandt == 0:
            # if divisible, update the dictionary to all established
            new_dict.update(prev_digits)
            # proceed to the next level of recursion with
            # the same eqparams, but updated digit dictionary,
            # new carry over and remaining digits to assign
            recurring_test = check_rec(eqparams,
                                (new_dict, dali, remaining_digits - set(newdigs)),
                                power + 1)
            # if the recursive call returned a non-empty dictionary
            # this means the recursion has found a solution
            # otherwise, proceed to the new permutation
            if recurring_test and len(recurring_test) > 0:
                return recurring_test
    # if no permutations are avaialble or no
    # permutation gave the result return None
    return None
def check_rec ( eqparams , trace_combo = ( { } , 0 , set ( range ( 10 ) ) ) , power = 0 ) : # Basic parameters of the equation, # maximal digit rank # characters with multipliers by rank # unique non-zero characters by rank # unique zero-allowed characters by rank # all unique characters by rank max_digit_rank , multipliers_chars , non_zero_chars , zero_chars , unique_chars = eqparams # recursion cumulative parameters # established characters with digits # carry-over from the previous level # remaining unassigned digits prev_digits , carry_over , remaining_digits = trace_combo # the maximal 10-power (beyond the maximal rank) # is reached if power == max_digit_rank : # Carry-over is zero, meaning solution is found if carry_over == 0 : return prev_digits else : # Otherwise the solution in this branch is not found # return empty return { } digit_letters = unique_chars [ power ] # all new unique letters from the current level part_sum = carry_over # Carry over from lower level remaining_exp = [ ] # TBD letters # Break down the current level letter into what can be # calculated in the partial sum and remaining TBD letter-digits for caesar , van_gogh in multipliers_chars [ power ] : if caesar in prev_digits : part_sum += van_gogh * prev_digits [ caesar ] else : remaining_exp . append ( ( caesar , van_gogh ) ) # Generate permutations for the remaining digits and currecnt level # non-zero letters and zero-allowed letters for newdigs in dig_perms ( remaining_digits , non_zero_chars [ power ] , zero_chars [ power ] ) : # build the dictionary for the new letters and this level new_dict = dict ( zip ( digit_letters , newdigs ) ) # complete the partial sum into test sum using the current permutation testsum = part_sum + sum ( [ new_dict [ caesar ] * van_gogh for caesar , van_gogh in remaining_exp ] ) # check if the sum is divisible by 10 dali , rembrandt = divmod ( testsum , 10 ) if rembrandt == 0 : # if divisible, update the dictionary to all established new_dict . update ( prev_digits ) # proceed to the next level of recursion with # the same eqparams, but updated digit dictionary, # new carry over and remaining digits to assign recurring_test = check_rec ( eqparams , ( new_dict , dali , remaining_digits - set ( newdigs ) ) , power + 1 ) # if the recursive call returned a non-empty dictionary # this means the recursion has found a solution # otherwise, proceed to the new permutation if recurring_test and len ( recurring_test ) > 0 : return recurring_test # if no permutations are avaialble or no # permutation gave the result return None return None