We have three numbers: ```123489, 5, and 67```.
With these numbers we form the list from their digits in this order ```[1, 5, 6, 2, 7, 3, 4, 8, 9]```.  It shouldn't take you long to figure out what to do to achieve this ordering.

Furthermore, we want to put a limit to the number of terms of the above list.

Instead of having 9 numbers, we only want 7, so we discard the two last numbers.

So, our list will be reduced to ```[1, 5, 6, 2, 7, 3, 4]``` (base list) 

We form all the possible arrays, from the list above, and we calculate, for each array, the addition of their respective digits.

See the table below: we will put only some of them
```
array for the list      sum (terms of arrays)
[1]                      1 # arrays with only one term (7 different arrays)
[5]                      5
[6]                      6
[2]                      2
[7]                      7
[3]                      3
[4]                      4

[1, 5]                   6 # arrays with two terms (42 different arrays)
[1, 6]                   7
[1, 2]                   3
[1, 7]                   8
[1, 3]                   4
[1, 4]                   5

.....                   ...
[1, 5, 6]               12 # arrays with three terms(210 different arrays)
[1, 5, 2]                8 
[1, 5, 7]               13 
[1, 5, 3]                9 
........                ...
[1, 5, 6, 2]            14 # arrays with four terms(840 different arrays)
[1, 5, 6, 7]            19 
[1, 5, 6, 3]            15 
[1, 5, 6, 4]            16 
............            ..
[1, 5, 6, 2, 7]         21 # arrays with five terms(2520 different arrays)
[1, 5, 6, 2, 3]         17 
[1, 5, 6, 2, 4]         18 
[1, 5, 6, 7, 2]         21 
...............         ..
[1, 5, 6, 2, 7, 3]      24 # arrays with six terms(5040 different arrays)
[1, 5, 6, 2, 7, 4]      25 
[1, 5, 6, 2, 3, 7]      24 
[1, 5, 6, 2, 3, 4]      21 
..................      .. 
[1, 5, 6, 2, 7, 3, 4]   28 # arrays with seven terms(5040 different arrays)
[1, 5, 6, 2, 7, 4, 3]   28   # arrays of max length = limit
[1, 5, 6, 2, 3, 7, 4]   28 
[1, 5, 6, 2, 3, 4, 7]   28 
:::::::::::::::::::::::::::
GreatT0talAdditions 328804 (GTA).(The total addition of the sum values corresponding to each permutation). A total 0f 13706 arrays, all of them different.
```
So we say that for the three numbers, ```123489, 5, and 67``` with a limit = ```7```, the GTA value is ```328804```.


Let's see now a case where we have digits occurring more than once. If we have a digit duplicated or more, just continue for the corresponding digit in turn of the next number. The result will be a list with no duplicated digits.

For the numbers: ```12348, 47, 3639 ``` with ``` limit = 8```  we will have the list ```[1, 4, 3, 2, 7, 6, 9, 8]``` (base list)

We should not have duplications in the permutations because there are no duplicated
digits in our base list.

For this case we have:
```
number of different array      number of terms the array has
              8                                  1 
             56                                  2 
            336                                  3
           1680                                  4
           6720                                  5
          20160                                  6
          40320                                  7
          40320                                  8
GTA = 3836040 with a limit of eight terms
```
The challenge: create the function ```gta()```, that receives a number that limits the amount of terms for the base list, ```limit```, and an uncertain number of integers that can have and will have different amount of digits that may have digits occuring more than once.

Just to understand the structure of the function will be like: ```gta(limit, n1, n2, ...nk)```

Let's see our functions with the examples shown above.
``` python
# case1
gta(7, 123489, 5, 67) == 328804 # base_list = [1, 5, 6, 2, 7, 3, 4]

# case2
gta(8, 12348, 47, 3639) == 3836040 # base_list = [1, 4, 3, 2, 7, 6, 9, 8]
```
You may assume that ```limit``` will be always lower or equal than the total available digits of all the numbers. The total available digits are all the digits of all the numbers. (E.g.the numbers ```12348, 47, 3639 ```have 8 available digits.)
You will always be receiving positive integers in an amount between 2 and 6.

For the tests ```limit <= 9``` (obviously).

Enjoy it!!

(Hint: the module itertools for python may be very useful, but there are many ways to solve it.)

(The arrays [1, 5, 6] and [1, 6, 5] have the same elements but are different arrays. The order matters)

Difficulty: interview

Starter code:

def gta(limit, *args):
	

Solutions:
import math

def gta(limit, *args):
    return sum_up(limit, make_pattern(limit, *args)) 

def binomial_coeff(n, k):
    """N choose K"""
    return math.factorial(n) / math.factorial(n-k)

def sum_up(limit, items):
    """
    Basic Idea: 
    
    The number of cominations is simply N choose K. We calcuate this n-times up to the limit.
    
    To sum up all the digits we don't have to calculate the sum of each permuation, rather, we simply have to 
    realise that the digit "1" will appear N times.
    
        For example: [1,2,3], pick = 3.  
        
        If there are 6 combinations of length 3 for 3 numbers then each number much appear once in each combination. 
        Thus the sum is: (1 * 6) + (2 * 6) + (3 * 6)
    
        In cases where we have N numbers and need to pick K of them then that means not all numbers appear in all combinations.
        It turns out combinations_total / (N / limit) gives us how many times N appears in the list of all combinations. 
        
        For example: [1,2,3] pick 2
        [1,2]
        [2,1]
        [1,3]
        [3,1]
        [2,3]
        [3,2]
        
        We can see that 1 appears 4/6 times. 
        combinations_total = 6, N = 3, limit = 2.
        
        6 / (3/2) = 4
    """
    total = 0
    for i in range(1, limit + 1):
        combin = binomial_coeff(len(items), i)
        ratio = len(items) / float(i) 

        for element in items:
            total += (element * (combin / ratio))

    return total
    
def make_pattern(limit, *args):

    seen = set()
    pattern = []
    items = list(map(str, args))
    
    k = 0
    while len(pattern) < limit:    
        for i in range(len(items)):
            try:
                v = items[i][k]
            except IndexError:
                pass
            
            if v not in seen:
                seen.add(v)
                pattern.append(int(v))
                if len(pattern) == limit:
                    break
        k += 1
    
    return pattern

def gta(limit, *args):
    args = [str(n).ljust(limit, '.') for n in args]
    unique, frequency, fact = set(), 0, 1
    for c in zip(*args):
        for d in c:
            if d == '.' or d in unique: continue
            limit -= 1
            unique.add(d)
            frequency += fact * len(unique)
            fact *= limit
            if not limit:
                return frequency * sum(map(int, unique))

def gta(limit, *args):
    ns = []
    for i in args:
        a = list(str(i))
        a.reverse()
        ns.append(a)
        
        
    base_list=[]
    while ns and len(base_list)<limit:
        n = ns.pop(0)
        if n:
            b = int(n.pop())
            if b not in base_list:
                base_list.append(b)
            if n:
                ns.append(n)
                
                
    base = sum(base_list)
    times = 0
    for i in range(1,1+limit):
        t = i
        for j in range(i-1):
            t *= limit - j - 1
        times += t
    return base*times



from math import e, factorial

def gta(limit, *nums):
    iternums, l, i, base= [(int(d) for d in str(n)) for n in nums], len(nums), 0, []
    while len(base) < limit:
        d, i = next(iternums[i % l], None), i+1
        if d is not None and d not in base:
            base.append(d)
    return (int(e * factorial(limit)) * (limit - 1) + 1) * sum(base) // limit


from math import factorial as fac
def gta(limit, *args): 
    x = [str(i) for i in args]
    y = set()
    while len(y) != limit:
        for i in range(len(args)):
            if x[i] != None:
                if len(x[i])!=0:
                    y.add(int(x[i][0]))
                if len(x[i]) == 1:
                    x[i] = None
                elif len(x[i])==2:
                    x[i] = x[i][1]
                else:
                    x[i] = x[i][1:]
                if len(y) == limit:
                    break
    y,l = list(y),len(y) 
    tot = [fac(l)/fac(i)*(sum(y)*1.0/l)*(l-i) for i in range(l)]
    return round(sum(tot),0)


import itertools

def gta(limit, *args): # find the base_list first

    x = max(len(str(l)) for l in args)

    y = ''
    for i in range(x):
        for ix in args:
            try:
              if str(ix)[i] in y:
                  continue
              y += str(ix)[i]
            except:
                pass
    ans = 0   
    for i in range(1, limit+1):
        for xc in itertools.permutations(y[:limit], i):
            ans += sum([sum(map(int, xc))])
    
    return ans

from itertools import cycle, permutations
def gta(limit, *args):
    nums = []
    numbers = [str(n) for n in args]
    for i in cycle(range(len(numbers))):
        if numbers[i]:
            if int(numbers[i][0]) not in nums:
                nums.append(int(numbers[i][0]))
                if len(nums) == limit: break
            numbers[i] = numbers[i][1:]
        elif "".join(numbers) == "": break
    ans = 0
    for n in range(1, len(nums) + 1):
        for arr in permutations(nums, n):
            ans += sum(arr)
    return ans