Search code examples
pythonmath

Find 'n' by decrementing numbers from 'z' with the amount of numbers equal to 'x'


Say I have n let's say it has a value of 27 now I have another variable lets say x is equals to 6 and a final variable z equals 9. We are going to find n by decrementing numbers from z with the amount of numbers equal to x.

For example, the number 27 should have an answer of 8 + 6 + 5 + 4 + 3 + 1 = 27 but the problem is you do not where to start, or how much the decrement value should be and also numbers cannot be duplicated. So the only solution I have now is to bruteforce it which takes soooo long. This is my current solution for it :

(idk if this works, I haven't got a "found" print)

for x in range(9**6):
    for a in range(9):
        for b in range(9):
            for c in range(9):
                for d in range(9):
                    for e in range(9):
                        for f in range(9):
                            _arr = [a, b, c, d, e, f]
                            arr = []
                            
                            for g in _arr:
                                if g not in _arr:
                                    arr.append(g)
                            
                            result = ((a + 1)  + (b + 1) + (c + 1) + (d + 1) + (e + 1) + (f + 1))
                            if len(arr) == 6 and result == 27 :
                                print(f"→ found! | answer : {result}")

What algorithms or theories should I use to solve this, or if its even possible? So far I've looked into GMP, Numpy libraries etc. but do not know in what way I would implement those.


Solution

  • There is no need to brute force this. You can start out by the minimum sum you can get with the number of terms (i.e., 1+2+3+4..). Then consider that the greatest value can be increased up to the maximum value. This increment can be applied to the second greatest as well, ...etc. We can determine by division how many of these increments we need. The remainder of this division will determine how much the greatest value that didn't change should be incremented.

    Here is an implementation:

    def solve(target, num_terms, max_value):
        total = num_terms * (num_terms + 1) // 2  # Triangular number
        if total > target:
            raise ValueError("target is too small")
        need = target - total
        diff = max_value - num_terms
        if need > num_terms * diff:
            raise ValueError("target is too great")
        shift = need // diff
        if num_terms == shift:
            return list(range(max_value - shift + 1, max_value + 1))
        return (
            list(range(1, num_terms - shift))
            + [num_terms - shift + (need % diff)]
            + list(range(max_value - shift + 1, max_value + 1))
        )
    

    Applied on the example in the question:

    print(solve(27, 6, 9))  # [1, 2, 3, 4, 8, 9]