Stella Octangula Number


In mathematics, a Stella Octangula number is a figurate number based on the Stella Octangula, of the form n(2n2 − 1).

Stella Octangula numbers which are perfect squares are 1 and 9653449.

Problem Statement

Given a number n, check whether it is the Stella Octangula number or not. The sequence of Stella Octangula numbers is 0, 1, 14, 51, 124, 245, 426, 679, 1016, 1449, 1990

Example1

Input

x = 14

Output

Yes

Explanation

$$\mathrm{For\: n = 2, expression \:n\lgroup 2n^2 – 1\rgroup is\: 14}$$

Example2

Input

n = 22

Output

No

Explanation

$$\mathrm{There \:is\: no\: n\: for\: which\: n(2n^2 – 1)\: is\: 22}$$

Solution

There are two possible solutions.

Approach 1

An easy method to solve this is finding the value of n(2n2 – 1) for n starting from 0 and then comparing it to the given number(consider it as x). We will keep on incrementing n and re-calculating n(2n2 – 1) until it becomes equal to x, which will mean that x is a Stella octangula number. We will stop if the value becomes greater than x, this would mean that x is not a Stella octangula number.

Pseudocode

Start
while n*(2*n*n - 1) is less than x
	n = n + 1
if n*(2*n*n - 1) is equal to x
	then return yes
else return false
End

Example

Below is a C++ program to check if the given number is a Stella octangula number or not using the above discussed approach.

#include <iostream>
using namespace std;
// Function to check the input number
int checkStellaOctangula(int x){
   // Initiating n from 0
   int n = 0;
   // Calculating n*(2*n*n - 1) for each n
   // and incrementing n if it is less than x
   while(n*(2*n*n - 1)<x){
      n++;
   }
   // checking if the value of an expression is equal to x
   // if it's equal, return true
   if(n*(2*n*n - 1)==x){
      return true;
   }
   // otherwise return false
   return false;
}
int main(){
   int x = 51;
   if (checkStellaOctangula(x)){  
      cout << "Yes";
   }
   else{
      cout << "No";
   }
   return 0;
}

Output

For input x = 52, the above C++ program will produce the following output −

Yes

Time complexity of this can go to O(x) as the upper bound.

Space complexity for this is O(1) as it doesn't use any extra space.

Approach 2

A more effective method of checking if the number is Stella Octangular or not is by using an Unbounded Binary Search.

In this method, we start from n = 1 and calculate the value of n(2n2 – 1) every time we double the value of i. We will do this until the value of expression n(2n2 – 1) is less than x.

After that, we will check if the value of the expression is equal to x or not. If it is equal to x then we return true, otherwise we make a call to binary search. In this call, we will compare the x with the value of expression n(2n2 – 1) in the range n/2 to n and return true if they are equal, else return false.

Pseudocode

Start
while n*(2*n*n - 1) is less than x
	n = n * 2
if n*(2*n*n - 1) is equal to x
	then return yes
else 
	Repeat until low>=high
	mid=(low+high)/2 
	If n*(2*n*n - 1) < x, 
		low=mid+1 
	Else If n*(2*n*n - 1) > x 
		high=mid-1
	else 
		return true
End

Example

Below is a C++ program to check if the given number is a Stella octangula number or not using the above discussed approach.

#include <bits/stdc++.h>
using namespace std;
// Function to calculate value of n*(2*n*n - 1)
int calculateExp(int n) {
   return n*(2*n*n - 1);
}
// Using binary search to search for a value of n for which
// expression has value equal to x
// where n lies in the interval (low to high)
// low is n/2 and high is n
bool binarySearch(int low, int high, int x){
   while (low <= high) {
      int mid = (low + high) / 2;
      if (calculateExp(mid) < x){
         low = mid + 1;
      }
      else if (calculateExp(mid) > x){
         high = mid - 1;
      }
     else{
         return true;
      }
   }
   return false;
}
// Function to check the input number
bool checkStellaOctangula(int x){
   // Edge case
   if (x == 0)
   return true;
   // Starting from n = 1 and doubling it
   // while the value of expression is less than x
   int n = 1;
   while (calculateExp(n) < x){
      n = n*2;
   }
   // If the expression is equal to x
   // return true
   if (calculateExp(n) == x){
      return true;
   }
   // Otherwise call binary search
   // range for the search decided by
   // finding value of expression for n
   // in range n/2 to n
 return binarySearch(n/2, n, x);
}

int main(){
   int x = 51;
   if (checkStellaOctangula(x)){ 
      cout << "Yes";
   }
   else{
      cout << "No";
   }
   return 0;
}

Output

For input x = 51, the above C++ program will produce the following output:

Yes

The time complexity is O(log n) as we are doubling the value of n for each iteration

Space complexity for this is O(1) as it doesn't use any extra space.

Conclusion

We discussed 2 methods. In 1st method we linearly incremented n and calculated n*(2*n*n - 1) for each value and compared it to x. This method was very slow and ineffective. In the 2nd method we doubled the value of n and then calculated n*(2*n*n - 1) and compared it to x, this is a much faster and effective method.

Updated on: 24-Aug-2023

63 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements