Search code examples
pythoncalgorithmmath

Calculate the sum of each possible continuous combination of a integer


Let's say I have a number for example 12345.
I want to calculate the sum each of all possible combinations for this number without changing the order of the digits, as followed:

12345
1234+5
123+45
123+4+5
12+345
12+34+5
12+3+45
12+3+4+5
1+2345
1+234+5
1+23+45
1+23+4+5
1+2+345
1+2+34+5
1+2+3+45
1+2+3+4+5

I am trying to find a way by doing multiple divisions (div and mod) and also using a for loop with 10^N step where N=[1,2,..,integer length].
The only thing I found is this https://math.stackexchange.com/questions/3031327/all-possible-ways-to-split-a-number

I have tried several modifications in a C and a Python script with no success.

The code I tried is the following code using C but this only breaks the number into different digits:

    int break_digits(int n) {
        int remain;
        int sum = 0;
        int original_number = n;
        while (n != 0) {
            remain= n % 10;
            sum+=remain;
            n /= 10;
        }
        return  sum;
    }

In Python I have found this code here https://www.techiedelight.com/break-string-non-overlapping-substrings/

    OPEN_BRACKET = '{'
    CLOSED_BRACKET = '}'
    EMPTY_STRING = ''
     
    # Function to break a string into all possible combinations of
    # non-overlapping substrings enclosed within parenthesis
    def recur(s, i=0, out=EMPTY_STRING):
        if i == len(s):
            print(out)
     
        # consider each substring S[i, j]
        for j in reversed(range(i, len(s))):
            substr = OPEN_BRACKET + s[i:j+1] + CLOSED_BRACKET
     
            # append the substring to the result and recur with an index of the
            # next character to be processed and the result string
            recur(s, j + 1, out + substr)
     
     
    if __name__ == '__main__':
        s = 'ABCD'    # input string
        recur(s)

I am still working on it in order to make it for numbers.
The main task is to create a function that you can give a number and returns the sum of all available continuous combinations.
Does anyone have a thought or hint so I can change the code?


Solution

  • Your post is still unclear as to whether you want (1) a collection of the possible sums found systematically, or (2) the grand sum of all these.

    This answer addresses (1); you could always sum them up to get (2). However, there are much faster ways to do (2) directly by counting the number of arrangements contain a particular contribution from each digit (e.g., 3 could contribute 3, 30 or 300 in your example 12345).

    Anyway, interpretation (1). You want the sum of each particular breakdown.

    Consider your example 12345. With 5 digits there are 5-1=4 internal positions where you could choose to put a plus or not. You could represent this set of choices by a binary code: for example, "1010" would correspond to 1+23+45" (i.e. you put a + after the 1 and the 3, but not after the 2 and the 4).

    So, all you need to do is cycle through the binary representations

    "0000", "0001", "0010", ...., "1111"

    and set up the relevant sums. This is done below by the binary representations of integers. Obviously you don't need to output the binary representation as well as the sum at the end, but it helps to show what is going on.

    If you want something else ... you'll have to clarify your post!

    N = int( input( "Input a positive number: " ) )
    
    # Get digits (in left-to-right order)
    digits = []
    while N > 0:
        digits.append( N % 10 )
        N = N // 10
    digits.reverse()
    
    numPlus = len( digits ) - 1
    for plusPositions in range( 0, 1 << numPlus ):
        # Get binary position of where to place + signs
        str = f"{plusPositions:0{numPlus}b}"
    
        # Form the sum described by these positions
        current = digits[0]
        sum = 0
        for b, d in zip( str, digits[1:] ):
            if b == '0':
                current = 10 * current + d
            else:
                sum += current
                current = d
        sum += current
        print( str, " ---> ", sum )
    

    Output:

    Input a positive number: 12345
    0000  --->  12345
    0001  --->  1239
    0010  --->  168
    0011  --->  132
    0100  --->  357
    0101  --->  51
    0110  --->  60
    0111  --->  24
    1000  --->  2346
    1001  --->  240
    1010  --->  69
    1011  --->  33
    1100  --->  348
    1101  --->  42
    1110  --->  51
    1111  --->  15