Last Updated: 16 Mar, 2021

Ways To Express

Hard
Asked in companies
Deutsche BankVisaGoldman Sachs

Problem statement

You are given the number ‘N’. The task is to find the number of ways to represent ‘N’ as a sum of two or more consecutive natural numbers.

Example:
N = 9
‘9’ can be represented as:
2 + 3 + 4 = 9
4 + 5 = 9
The number of ways to represent ‘9’ as a sum of consecutive natural numbers is ‘2’. So, the answer is ‘2’.
Note:
1. The numbers used to represent ‘N’ should be natural numbers (Integers greater than equal to 1).
Input format:
The first line of input contains an integer ‘T’ which denotes the number of test cases. Then, the ‘T’ test cases follow.

The first line and only line of each test case contain a single integer ‘N’, where ‘N’ is the given number.
Output format:
For every test case, print a single line containing a single integer denoting the number of ways to represent ‘N’ as a sum of two or more consecutive natural numbers. 

The output of each case will be printed in a separate line.
Note:
You do not need to print anything. It has already been taken care of. Just implement the given function.
Constraints:
1 <= T <= 1000
3 <= N <= 10 ^ 5

Where ‘T’ is the number of test cases, and ‘N’ is the given number.

Time limit: 1 second

Approaches

01 Approach

Use a prefix sum array ‘prefixSum’ (with ‘prefixSum[0] = 0’) whose each index ‘i’ stores the sum of ‘i’ consecutive integers starting from ‘1’. The size of this array will be ‘x’. Here, ‘x + (x-1) <= n’,i.e, when the sum of two consecutive numbers becomes greater than ‘n’. To generate ‘prefixSum’ iterate from index ‘i = 1’ and compute ‘prefixSum[i] = prefixSum[i - 1] + i’. Let, ‘count’ is the number of ways to represent ‘n’ as the sum of consecutive numbers. For an index ‘i’ if the value ‘prefixSum[i] - n’ is present in ‘prefixSum[j]’ (at some index ‘j’) then the sum of numbers from ‘j + 1’ to ‘i’ is equal to ‘n’, increase ‘count’ by ‘1’. Also, if ‘prefixSum[i] - n = 0’ (when ‘prefixSum[i] = n’) increase ‘count’ by ‘1’.

 

For example: Let, ‘n = 15’

So ‘2x -1 <= 15’, we get ‘x <= 8’ (Size of ‘prefixSum’ is 8)

‘prefixSum’ = [0, 1, 3, 6, 10, 15, 21, 28, 36]

‘prefixSum[i] - n’ = [-15, -14, -12, -9, -5, 0, 6, 13, 21]

Here, ‘0’, ‘6’, and ‘21’ are present in ‘prefixSum’, so ‘count = 3’. Hence, the answer is ‘3’.

 

So, for each index ‘i’ if the value ‘prefixSum[i] - n’ exists in the ‘prefixSum’ array, increase ‘count’ by ‘1’. We can use a hash map to find if ‘prefixSum[i] - n’ is present in the ‘prefixSum’ array.

 

Algorithm:

  • Create a hash map ‘prefixMap’. Use it to store the prefix sums. Initially ‘prefixMap’ contains a single value ‘0’.
  • Initialize an integer ‘count = 0’ and ‘prefixSum = 0’. Use ‘count’ to count the number of ways to represent ‘n’ as the sum of consecutive numbers and ‘prefixSum’ to store the prefix sum at index ‘i’.
  • Run a loop where ‘i’ ranges from ‘1’ to ‘x’, here ‘x = (n+1)/2’:
    • ‘prefixSum = prefixSum + i’.
    • Insert the value of ‘prefixSum’ in ‘prefixMap’.
    • If ‘prefixMap’ contains ‘prefixSum - n’, then:
      • ‘count++’
  • Return ‘count’ as the answer.

02 Approach

Use a queue to keep track of consecutive numbers whose sum is less than or equal to ‘n’. Initialize the queue with numbers from ‘1’ to ‘x’ such that their sum is less than or equal to ‘n’. If the sum is equal to ‘n’, then increase the answer by ‘1’. Now, add ‘x+1’ to the queue and remove numbers from the queue until the queue’s sum is less than or equal to ‘n’. Again, if the sum is equal to ‘n’, then increase the answer by ‘1’. Continue this process until ‘x + y’ where ‘(x + y) + (x + y - 1)’ is greater than ‘n’,i.e., stop the process when the sum of two consecutive numbers becomes greater than ‘n’.

 

Algorithm:

  • Create an empty queue ‘numQueue’.
  • Initialize two integers ‘count = 0’ and ‘sum = 0’. Use ‘count’ to count the number of ways to represent ‘n’ as the sum of consecutive numbers and ‘sum’ to store the sum of numbers in ‘numQueue’.
  • Initialize ‘x’ to ‘1’ and run a loop while ‘2 * x - 1 <= n’:
    • Insert ‘x’ at the end of ‘numQueue’.
    • ‘sum += x’. Update ‘sum’ with ‘x’.
    • Run a loop while ‘sum > n’:
      • ‘sum = sum - numQueue.front()’.
      • Remove the number at the front of ‘numQueue’.
    • If ‘sum’ is equal to ‘n’, then ‘count++’.
  • Return ‘count’ as the answer.

03 Approach

Represent ‘n’ as the sum of ‘i + 1’ consecutive numbers starting from ‘x’:

‘n = (x) + (x + 1) + .... + (x + i)’

‘n = x * (i + 1) + (i*(i + 1)) / 2’ (Sum of arithmetic progression)

We have, ‘x = (2 * n - i * (i + 1))/(i + 1)’

 

Here, ‘x’ is a natural number. For ‘x’ to be positive, we can substitute ‘i’ from ‘1’ till ‘2 * n - i * (i + 1) > 0’. For this range of ‘i’, ‘x’ should not be a fraction,i.e., the numerator - ‘2 * n - i * (i+1)’ should be divisible by the denominator - ‘i + 1’.

 

Algorithm:

  • Initialize two integers ‘count = 0’ and ‘numerator = 2*n - 2’. Use ‘count’ to count the number of ways to represent ‘n’ as the sum of consecutive numbers and ‘numerator’ to store the numerator of the corresponding value of ‘i’ (initialize for ‘i = 1’).
  • Initialize ‘i = 1’ and run a loop where ‘numerator’ is greater than ‘0’:
    • If ‘numerator’ is divisible by ‘2 * (i+1)’, then ‘count++’. The denominator is equal to ‘2 * (i+1)’.
    • ‘i++’.
    • ‘numerator = 2 * n - i * (i + 1)’. Update ‘numerator’ with the new value of ‘i’.
  • Return ‘count’ as the answer.