-1

Hello Guys I am trying to solve one problem given on the Hacker Rank. Though the problem is quite simple, I was thinking to solve the problem using some other concepts.

The problem is

Desription

You are given an integer N. Find the digits in this number that exactly divide N (division that leaves 0 as remainder) and display their count. For N=24, there are 2 digits (2 & 4). Both of these digits exactly divide 24. So our answer is 2.

Input Format

The first line contains T (the number of test cases), followed by T lines (each containing an integer N).

Constraints 1≤T≤15 0

I solved the problem earlier by defining variable N as of type long long but that i guess will not be the efficient way to solve the problem. So i thought why not declare the variable N as an character array. This way we can also use the program to store the number greater then the max limit of long long also rt?

Say i used the following code

#include <stdio.h>
#include <string.h>
int main()
{
    int i,t;
    char n[20];
    scanf("%d",&t);
    while(t--)
    {    
        scanf("%s",n);
       int len=strlen(n);
       int f2,f3,f5,f7,f4,count;
         f2=f3=f5=f7=f4=count=0;
      for( i=0;i<len;++i)
     { int sum=0;
         switch((int)n[i])
         {
             case 48: break;
             case 49: ++count;break;
             case 50: if((int)n[len-1]%2==0)      // divisibility by 2
                      { 
                         ++count;f2=1;
                      }break;
             case 51:  for(i=0;n[i]!='\0';++i)    // divisibility by 3
                     {
                         sum+=(int)n[i];
                     }
                     if(sum%3==0)
                    {
                          ++count;
                         f3=1;
                     }break;
            case 52: if(f2==1)             // divisibility by 4
                     {
                        ++count;
                        f4=1;
                    }    break;
            case 53: if(n[len-1]=='5' || n[len-1]=='0')    // divisibility by 5
                     {
                         ++count;
                         f5=1;
                     }break;
            case 54: if(f2==1 && f3==1)         // divisibility by 6
                     {
                         ++count;
                         break;
                     }  
             case 55: // Code for divisibilty by 7
            case 56: if(f2==1 && f4==1)    // divisibility by 8
                     {    ++count;
                          break;
                     }
            case 57: if(f3==1)       // divisibility by 9
                    { 
                        ++count;
                        break;
                    }    
        }

    }

    printf("%d\n",count);
    }
    return 0;
}

The program is working fine but the only problem is I am not able to rt the code for divisibility by 7 anu suggestions will be helpful, And also which is the better way to solve the problem , This way in which the variable N is declared as the character array or by declaring the variable N as long long.

Any improvements for the above code would also be appreciated .....:)

Patel
  • 87
  • 8
  • FIX YOUR FORMATTING, it hurts in the eyes – DrKoch Apr 06 '15 at 11:45
  • What is the upper limit for N? – DrKoch Apr 06 '15 at 11:46
  • Upper limit for N is 10^10 – Patel Apr 06 '15 at 11:53
  • Upper limit for `long long` is about 10^20 (see http://www.cplusplus.com/reference/climits/) so why do you go through all this? (instead of just using `long long n` and `n%digit == 0`) – DrKoch Apr 06 '15 at 12:00
  • Just to solve the question with some other logic, And i guess this is more efficient way in terms of complexity rt ? – Patel Apr 06 '15 at 12:03
  • Bad style leads to bad bugs! Consider using character constants such as `'0'` instead of ascii char numbers in the `switch`. Also note that cases `54` to `57` have missing `break` statements. – chqrlie Apr 06 '15 at 18:25

1 Answers1

0

Divisibility by 7 can be checked by this rule

Also you can use this mod() function to check divisibility by any number :

    int mod(char *n, int val)
    {
        int sum = 0;
        for(int i=0; n[i]; i++)
        {
            sum = sum*10 + (n[i]-'0');
            if(sum >= val)
              sum = sum % val;
        }
        return sum;
    }

it will return 0, if the number n is divisible by number val :)

And you don't need to check for every redundant digit.
First check the available digit then check for divisibility once for each digit.
Here's what you can do -

#include <stdio.h>
#include <string.h>
int mod(char *n, int val)
{
    int sum = 0;
    for(int i=0; n[i]; i++)
    {
        sum = sum*10 + (n[i]-'0');
        if(sum >= val)
          sum = sum % val;
    }
    return sum;
}
int main()
{
    int i,t;
    int digit[10];
    char n[20];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",n);
        int len=strlen(n);
        int cnt=0;
        memset(digit,0,sizeof(digit)); // setting all the digit to 0
        for(i=0;i<len;i++)
          digit[n[i]-'0']++;
        for(i=1;i<10;i++)
        {
            if(digit[i]==0) // number doesn't contain any of this digit
              continue;
            if(mod(n,i)==0)
                cnt+=digit[i]; // Adding the digit to the answer
        }
        printf("%d\n",cnt);
    }
    return 0;
}

How this works :

for n = 147 and val = 7
sum = 0

1st iter >> sum = 0*10 + 1 = 1
sum < val, so continue

2nd iter >> sum = 1*10 + 4 = 14
sum >= val, so sum = sum % val = 14 % 7 = 0

3rd iter >> sum = 0*10 + 7 = 7
sum >= val, so sum = sum % val = 7 % 7 = 0

as the final sum is 0, so we can say that n is divisible by val :)
Ali Akber
  • 3,670
  • 3
  • 26
  • 40