Open In App

Number of compositions of a natural number

Last Updated : 28 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a natural number n, find the number of ways in which n can be expressed as a sum of natural numbers when order is taken into consideration. Two sequences that differ in the order of their terms define different compositions of their sum. 
Examples: 
 

Input :  4
Output : 8
Explanation
All 8 position composition are:
4, 1+3, 3+1, 2+2, 1+1+2, 1+2+1, 2+1+1
and 1+1+1+1
Input : 8
Output : 128

 

A Simple Solution is to generate all compositions and count them.
Using the concept of combinatorics, it can be proved that any natural number n will have 2^(n-1) distinct compositions when order is taken into consideration.
 

One way to see why the answer is 2^(n-1) directly is to write n as a sum of 1s: 
n = 1 + 1 + 1 +…+ 1 (n times).
There are (n-1) plus signs between all 1s. For every plus sign we can choose to split ( by putting a bracket) at the point or not split. Therefore answer is 2^(n-1).
For example, n = 4 
No Split 
4 = 1 + 1 + 1 + 1 [We write as single 4]
Different ways to split once 
4 = (1) + (1 + 1 + 1) [We write as 1 + 3] 
4 = (1 + 1) + (1 + 1) [We write as 2 + 2] 
4 = (1 + 1 + 1) + (1) [We write as 3 + 1]
Different ways to split twice 
4 = (1) + (1 + 1) + (1) [We write as 1 + 2 + 1] 
4 = (1 + 1) + (1) + (1) [We write as 2 + 1 + 1] 
4 = (1) + (1) + (1 + 1) [We write as 1 + 1 + 2]
Different ways to split three times 
4 = (1) + (1) + (1) + (1) [We write as 1 + 1 + 1 + 1]
Since there are (n-1) plus signs between the n 1s, there are 2^(n-1) ways of choosing where to split the sum, and hence 2^(n-1) possible sums .

 

C++




// C++ program to find the total number of
// compositions of a natural number
#include<iostream>
using namespace std;
 
#define ull unsigned long long
 
ull countCompositions(ull n)
{
    // Return 2 raised to power (n-1)
    return (1L) << (n-1);
}
 
// Driver Code
int main()
{
    ull n = 4;
    cout << countCompositions(n) << "\n";
    return 0;
}


Java




// Java program to find
// the total number of
// compositions of a
// natural number
import java.io.*;
import java.util.*;
 
class GFG
{
public static int countCompositions(int n)
{
    // Return 2 raised
    // to power (n-1)
    return 1 << (n - 1);
}
 
// Driver Code
public static void main(String args[])
{
    int n = 4;
    System.out.print(countCompositions(n));
}
}
 
// This code is contributed by
// Akanksha Rai(Abby_akku)


Python




# Python code to find the total number of
# compositions of a natural number
def countCompositions(n):
 
    # function to return the total number
    # of composition of n
    return (2**(n-1))
 
# Driver Code
print(countCompositions(4))


C#




// C# program to find the
// total number of compositions
// of a natural number
using System;
 
class GFG
{
public static int countCompositions(int n)
{
    // Return 2 raised
    // to power (n-1)
    return 1 << (n - 1);
}
 
// Driver Code
public static void Main()
{
    int n = 4;
    Console.Write(countCompositions(n));
}
}
 
// This code is contributed by mits


Javascript




<script>
 
// javascript program to find
// the total number of
// compositions of a
// natural number
 
function countCompositions(n)
{
    // Return 2 raised
    // to power (n-1)
    return 1 << (n - 1);
}
 
// Driver Code
 
    var n = 4;
    document.write(countCompositions(n));
 
 
 
// This code is contributed by 29AjayKumar
</script>


PHP




<?php
// PHP program to find the
// total number of compositions
// of a natural number
 
function countCompositions($n)
{
    // Return 2 raised
    // to power (n-1)
    return ((1) << ($n - 1));
}
 
// Driver Code
$n = 4;
echo countCompositions($n), "\n";
     
// This code is contributed
// by ajit
?>


Output: 
 

8

This article is contributed by Sruti Rai .

 Approach#2: Recursion with Memoization

The code uses memoization to efficiently calculate the number of compositions of a given integer using positive integers. The main function, count_compositions_memo, initializes a memo dictionary, and calls the recursive function count_compositions to calculate the result. The count_compositions function uses memoization to avoid redundant calculations, and computes the number of compositions recursively by iterating over all possible values of the first element in the composition and adding up the number of compositions for the remaining sum.

Algorithm

1. Create a dictionary ‘memo’ to store previously computed values.
2. Define a recursive function ‘count_compositions’ which takes n as input.
3. If n == 0, return 1.
4. If n < 0, return 0.
5. If memo[n] is not None, return memo[n].
6. Set memo[n] to 0.
7. Loop from i = 1 to i = n:
a. Add count_compositions(n-i) to memo[n].
8. Return memo[n].
9. Call count_compositions(n) and return its value.

C++




#include <iostream>
#include <unordered_map> // include the unordered_map library for memoization
 
int count_compositions_memo(int n) {
    std::unordered_map<int, int> memo; // create a memoization table
    if (n == 0) {
        return 1; // base case: there is only one way to compose 0
    }
    if (n < 0) {
        return 0; // base case: there is no way to compose a negative number
    }
    if (memo.find(n) != memo.end()) {
        return memo[n]; // if n is in the memoization table, return its value
    }
    int count = 0;
    for (int i = 1; i <= n; i++) {
        count += count_compositions_memo(n - i); // recursively count the number of compositions
    }
    memo[n] = count; // store the computed value in the memoization table
    return count;
}
 
int main() {
    int n = 4;
    std::cout << count_compositions_memo(n) << std::endl;
    return 0;
}


Java




import java.util.HashMap;
import java.util.Map;
 
public class CompositionCount {
 
    // Function to count compositions with memoization
    public static int countCompositionsMemo(int n) {
        // Create a memoization table using a HashMap
        Map<Integer, Integer> memo = new HashMap<>();
         
        // Base case: there is only one way to compose 0
        if (n == 0) {
            return 1;
        }
         
        // Base case: there is no way to compose a negative number
        if (n < 0) {
            return 0;
        }
         
        // If n is in the memoization table, return its value
        if (memo.containsKey(n)) {
            return memo.get(n);
        }
         
        int count = 0;
        // Recursively count the number of compositions
        for (int i = 1; i <= n; i++) {
            count += countCompositionsMemo(n - i);
        }
         
        // Store the computed value in the memoization table
        memo.put(n, count);
         
        return count;
    }
 
    public static void main(String[] args) {
        int n = 4;
        // Calculate and print the number of compositions for n
        System.out.println(countCompositionsMemo(n));
    }
}


Python3




def count_compositions_memo(n):
    memo = {}
    def count_compositions(n):
        if n == 0:
            return 1
        if n < 0:
            return 0
        if n in memo:
            return memo[n]
        memo[n] = 0
        for i in range(1,n+1):
            memo[n] += count_compositions(n-i)
        return memo[n]
    return count_compositions(n)
 
n=4
print(count_compositions_memo(n))


C#




using System;
using System.Collections.Generic;
 
class Program {
    static int
    CountCompositionsMemo(int n, Dictionary<int, int> memo)
    {
        if (n == 0) {
            return 1; // base case: there is only one way to
                      // compose 0
        }
        if (n < 0) {
            return 0; // base case: there is no way to
                      // compose a negative number
        }
        if (memo.ContainsKey(n)) {
            return memo[n]; // if n is in the memoization
                            // table, return its value
        }
        int count = 0;
        for (int i = 1; i <= n; i++) {
            count += CountCompositionsMemo(
                n - i, memo); // recursively count the
                              // number of compositions
        }
        memo[n] = count; // store the computed value in the
                         // memoization table
        return count;
    }
 
    static int CountCompositions(int n)
    {
        Dictionary<int, int> memo
            = new Dictionary<int, int>();
        return CountCompositionsMemo(n, memo);
    }
 
    static void Main()
    {
        int n = 4;
        Console.WriteLine(CountCompositions(n));
    }
}


Javascript




// Function to count compositions with memoization
function countCompositionsMemo(n) {
    // Create a memoization table using a Map
    const memo = new Map();
 
    // Base case: there is only one way to compose 0
    if (n === 0) {
        return 1;
    }
 
    // Base case: there is no way to compose a negative number
    if (n < 0) {
        return 0;
    }
 
    // If n is in the memoization table, return its value
    if (memo.has(n)) {
        return memo.get(n);
    }
 
    let count = 0;
    // Recursively count the number of compositions
    for (let i = 1; i <= n; i++) {
        count += countCompositionsMemo(n - i);
    }
 
    // Store the computed value in the memoization table
    memo.set(n, count);
 
    return count;
}
 
// Example usage
const n = 4;
// Calculate and print the number of compositions for n
console.log(countCompositionsMemo(n));


Output

8


Time complexity: O(n^2)
Auxiliary Space: O(n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads