Write a program to findNth Ugly Number - Codeprg

Breaking

programing News Travel Computer Engineering Science Blogging Earning

Tuesday 9 July 2019

Write a program to findNth Ugly Number

Write a program to findNth Ugly Number.

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … shows the first 11 ugly numbers. By convention, 1 is included. 

Examples:
  • Loop for all positive integers until ugly number count is smaller than n, if an integer is ugly than increment ugly number count.
  • To check if a number is ugly, divide the number by greatest divisible powers of 2, 3 and 5, if the number becomes 1 then it is an ugly number otherwise not.

For example, let us see how to check for 300 is ugly or not. Greatest divisible power of 2 is 4, after dividing 300 by 4 we get 75. Greatest divisible power of 3 is 3, after dividing 75 by 3 we get 25. Greatest divisible power of 5 is 25, after dividing 25 by 25 we get 1. Since we get 1 finally, 300 is ugly number.

Input  : n = 7
Output : 8

Input  : n = 10
Output : 12

Input  : n = 15
Output : 24

Input  : n = 150
Output : 5832
# include<stdio.h> 
# include<stdlib.h> 
  
/*This function divides a by greatest divisible  
  power of b*/
int maxDivide(int a, int b) 
{ 
  while (a%b == 0) 
   a = a/b;  
  return a; 
}     
  
/* Function to check if a number is ugly or not */
int isUgly(int no) 
{ 
  no = maxDivide(no, 2); 
  no = maxDivide(no, 3); 
  no = maxDivide(no, 5); 
    
  return (no == 1)? 1 : 0; 
}     
  
/* Function to get the nth ugly number*/
int getNthUglyNo(int n) 
{ 
  int i = 1;  
  int count = 1;   /* ugly number count */ 
  
  /*Check for all integers untill ugly count  
    becomes n*/ 
  while (n > count) 
  { 
    i++;       
    if (isUgly(i)) 
      count++;  
  } 
  return i; 
} 
  
/* Driver program to test above functions */
int main() 
{ 
    unsigned no = getNthUglyNo(150); 
    printf("150th ugly no. is %d ",  no); 
    getchar(); 
    return 0; 
} 

Method 2 (Use Dynamic Programming) Here is a time efficient solution with O(n) extra space. The ugly-number sequence is 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …      because every number can only be divided by 2, 3, 5, one way to look at the sequence is to split the sequence to three groups as below:      (1) 1×2, 2×2, 3×2, 4×2, 5×2, …      (2) 1×3, 2×3, 3×3, 4×3, 5×3, …      (3) 1×5, 2×5, 3×5, 4×5, 5×5, …
     We can find that every subsequence is the ugly-sequence itself (1, 2, 3, 4, 5, …) multiply 2, 3, 5. Then we use similar merge method as merge sort, to get every ugly number from the three subsequence. Every step we choose the smallest one, and move one step after.
  • initialize
       ugly[] =  | 1 |
       i2 =  i3 = i5 = 0;
    
    First iteration
       ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
                = Min(2, 3, 5)
                = 2
       ugly[] =  | 1 | 2 |
       i2 = 1,  i3 = i5 = 0  (i2 got incremented ) 
    
    Second iteration
        ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
                 = Min(4, 3, 5)
                 = 3
        ugly[] =  | 1 | 2 | 3 |
        i2 = 1,  i3 =  1, i5 = 0  (i3 got incremented ) 
    
    Third iteration
        ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
                 = Min(4, 6, 5)
                 = 4
        ugly[] =  | 1 | 2 | 3 |  4 |
        i2 = 2,  i3 =  1, i5 = 0  (i2 got incremented )
    
    Fourth iteration
        ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
                  = Min(6, 6, 5)
                  = 5
        ugly[] =  | 1 | 2 | 3 |  4 | 5 |
        i2 = 2,  i3 =  1, i5 = 1  (i5 got incremented )
    
    Fifth iteration
        ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
                  = Min(6, 6, 10)
                  = 6
        ugly[] =  | 1 | 2 | 3 |  4 | 5 | 6 |
        i2 = 3,  i3 =  2, i5 = 1  (i2 and i3 got incremented )
    
    Will continue same way till I < 150
    • # include<bits/stdc++.h> 
    using namespace std; /* Function to get the nth ugly number*/ unsigned getNthUglyNo(unsigned n) { unsigned ugly[n]; // To store ugly numbers unsigned i2 = 0, i3 = 0, i5 = 0; unsigned next_multiple_of_2 = 2; unsigned next_multiple_of_3 = 3; unsigned next_multiple_of_5 = 5; unsigned next_ugly_no = 1; ugly[0] = 1; for (int i=1; i<n; i++) { next_ugly_no = min(next_multiple_of_2, min(next_multiple_of_3, next_multiple_of_5)); ugly[i] = next_ugly_no; if (next_ugly_no == next_multiple_of_2) { i2 = i2+1; next_multiple_of_2 = ugly[i2]*2; } if (next_ugly_no == next_multiple_of_3) { i3 = i3+1; next_multiple_of_3 = ugly[i3]*3; } if (next_ugly_no == next_multiple_of_5) { i5 = i5+1; next_multiple_of_5 = ugly[i5]*5; } } /*End of for loop (i=1; i<n; i++) */ return next_ugly_no; } /* Driver program to test above functions */ int main() { int n = 150; cout << getNthUglyNo(n); return 0; }