Thread: is there a way of simplifying this

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    is there a way of simplifying this

    As title the problem is to workout how many prime numbers can be written in all rotations and still be prime.

    Ie 193939, 939391, 393919, 939193, 391939, 919393 are all prime numbers. Here is my effort

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    #define Limit 1000000
    
    int IsPrime( char *, int );
    int NumRotate( char *, int );
    
    int main()
    {
        unsigned long Counter = 1;
        char NumSieve[Limit] = { 0 };
    
        for( int i = 4; i < Limit; i += 2 )
        {
            NumSieve[ i - 1 ] = 1;
        }
    
    
        for ( int i = 3; i < 1000; i += 2 ) //only test odd numbers
        {
            if ( NumSieve[ i - 1 ] == 0 )
            {
               for ( int j = 2 * i; j < Limit; j += i )
               {
                    NumSieve[ j - 1 ] = 1;
               }
            }
        }
    
        for ( int i = 3; i < Limit; i++ )
        {
            if ( NumSieve[ i - 1 ] == 0 )
            {
                if ( NumRotate( NumSieve, i ) == 1)
                {
                    Counter++;
                }
    
            }
        }
        printf("number of rotatable primes between 1 and %d is %lu\n", Limit, Counter);
    
        return 0;
    }
    
    int IsPrime( char *PNums, int x )
    {
         return PNums[ x - 1 ] == 0 ? 1 : -1;
    }
    
    int NumRotate( char *PNums, int x )
    {
        if ( x % 10 == x) //single digit number so no need to test
        {
            return 1;
        }
        else if ( x % 100 == x ) // 2 digit number
        {
            int SecondDigit = x % 10, FirstDigit = ( x - SecondDigit ) / 10;
            if ( IsPrime( PNums, SecondDigit * 10 + FirstDigit ) == -1 )
            {
                return -1;
            }
        }
        else if ( x % 1000 == x ) //3 digits
        {
            int FirstDigit = ( x - x % 100 ) / 100, ThirdDigit = x % 10;
            int SecondDigit = ( x - ( FirstDigit * 100 + ThirdDigit ) ) / 10, loop = 2;
    
            do
            {
                int tmp = FirstDigit;
    
                FirstDigit = SecondDigit;
                SecondDigit = ThirdDigit;
                ThirdDigit = tmp;
    
                if ( FirstDigit == 0 )
                    return -1;
    
                if ( IsPrime( PNums, ( FirstDigit * 100 ) + ( SecondDigit * 10 ) + ThirdDigit ) == -1 )
                {
                    return -1;
                }
    
                --loop;
            } while ( loop > 0 );
        }
        else if ( x % 10000 == x ) //4 digits
        {
            int FirstDigit = ( x - x % 1000) / 1000, FourthDigit = x % 10, Loop = 3;
            int ThirdDigit = ( x % 100 - FourthDigit ) / 10, SecondDigit = (( x - x  % 100) / 100 ) % 10;
    
            do
            {
                int tmpNum = FirstDigit;
    
                FirstDigit = SecondDigit;
                SecondDigit = ThirdDigit;
                ThirdDigit = FourthDigit;
                FourthDigit = tmpNum;
    
                if ( FirstDigit == 0 )
                    return -1;
    
                if ( IsPrime( PNums, ( FirstDigit * 1000) + ( SecondDigit * 100 ) + ( ThirdDigit * 10 ) + FourthDigit ) == -1 )
                    return -1;
    
                --Loop;
            } while ( Loop > 0 );
        }
        else if ( x % 100000 == x ) // 5 digits
        {
            int FirstDigit = ( x - x % 10000) / 10000, FithDigit = x % 10, FourthDigit = ( x % 100 - FithDigit ) / 10, Loop = 4;
            int ThirdDigit = ( x % 1000 - ( FourthDigit * 10 + FithDigit ) ) / 100;
            int SecondDigit = ( x % 10000 - ( ThirdDigit * 100 + FourthDigit * 10 + FithDigit ) ) / 1000;
    
            do
            {
                int TmpNum = FirstDigit;
    
                FirstDigit = SecondDigit;
                SecondDigit = ThirdDigit;
                ThirdDigit = FourthDigit;
                FourthDigit = FithDigit;
                FithDigit = TmpNum;
    
                if ( FirstDigit == 0 )
                    return -1;
    
                if ( IsPrime( PNums, ( FirstDigit * 10000) + ( SecondDigit * 1000 ) + ( ThirdDigit * 100 ) + ( FourthDigit * 10 ) + FithDigit ) == -1 )
                    return -1;
    
                --Loop;
            } while (Loop > 0 );
        }
        else if ( x % 1000000 ) // 6 digits
        {
            int FirstDigit = ( x - x % 100000 ) / 100000, SixthDigit = x % 10, FithDigit = ( x % 100 - SixthDigit ) / 10, Loop = 5;
            int FourthDigit = ( x % 1000 - ( FithDigit * 10 ) + SixthDigit ) / 100;
            int ThirdDigit = ( x % 10000 - ( FourthDigit * 100 ) + ( FithDigit * 10 ) + SixthDigit ) /1000;
            int SecondDigit = ( x % 100000 - ( ThirdDigit * 1000) + ( FourthDigit * 100 ) + ( FithDigit * 10 ) + SixthDigit ) / 10000;
    
            do
            {
                int TmpNum = FirstDigit;
    
                FirstDigit = SecondDigit;
                SecondDigit = ThirdDigit;
                ThirdDigit = FourthDigit;
                FourthDigit = FithDigit;
                FithDigit = SixthDigit;
                SixthDigit = TmpNum;
    
                if ( FirstDigit == 0 )
                    return -1;
    
                if ( IsPrime( PNums, ( FirstDigit * 100000) + ( SecondDigit * 10000 ) + ( ThirdDigit * 1000 ) + ( FourthDigit * 100 ) + ( FithDigit * 10 ) + SixthDigit ) == -1 )
                    return -1;
    
                --Loop;
            } while (Loop > 0 );
        }
    
        return 1;
    }
    It works and i get the correct answer but the rotate function is awkward

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    > NumSieve[ i - 1 ] = 1;
    Why did you make it complicated by having -1 in there?


    Code:
    int IsPrime( char *PNums, int x )
    {
         return PNums[ x - 1 ] == 0 ? 1 : -1;
    }
    Functions written as boolean predicates should return boolean values.

    Code:
    int IsPrime( char *PNums, int x )
    {
         return PNums[ x - 1 ] == 0;
    }
    Which results in more readable code.
    Code:
    if ( IsPrime(pNums, x) ) {
      // do something
    }

    > but the rotate function is awkward
    Yeah, whenever you start reaching for the ctrl-c / ctrl-v key combo to make multiple copies of the code, you need to step back and think about what you're doing.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void numlen(int num, int *power, int *len) {
        *power = 1;
        *len = 1;
        while ( num >= 10 ) {
            (*power) *= 10;
            (*len)++;
            num /= 10;
        }
    }
    
    int rotate(int num) {
        int power, len;
        numlen(num,&power,&len);
        for ( int i = 0 ; i < len ; i++ ) {
            int high = num / power;
            int rem = num % power;
            num = rem * 10 + high;
            printf("Num=%d\n", num );
        }
    }
    
    int main ( ) {
        rotate(6);
        rotate(42);
        rotate(107);
        rotate(123456);
    }
    
    $ ./a.out 
    Num=6
    Num=24
    Num=42
    Num=71
    Num=710
    Num=107
    Num=234561
    Num=345612
    Num=456123
    Num=561234
    Num=612345
    Num=123456
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    > NumSieve[ i - 1 ] = 1;
    >Why did you make it complicated by having -1 in there?

    because index 0 = 1 therefore index 3 = 4 i did try and get index 0 = 2 as 1 isn't used but it didn't want to play nicely.

    on lines 5 and 6 of your version you used *power and *len to assign values to them but on lines 8 and 9 you used (*power) and (*len) may i ask why?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    While
    (*power) *= 10;
    is the same as
    *power *= 10;

    (*len)++;
    is most definitely NOT the same as
    *len++;
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    could you say *len += 1 and get the same result as (*len)++

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    Yes.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simplifying fractions
    By Eve Wein in forum C Programming
    Replies: 1
    Last Post: 11-16-2020, 03:28 AM
  2. Need help simplifying for loop
    By tmdm in forum C Programming
    Replies: 3
    Last Post: 03-15-2011, 12:58 PM
  3. Simplifying Fractions
    By kemiga in forum C Programming
    Replies: 7
    Last Post: 10-20-2010, 07:49 AM
  4. Need help simplifying
    By yigster in forum C Programming
    Replies: 8
    Last Post: 04-01-2009, 07:28 AM
  5. Simplifying fractions in c++
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 09-01-2002, 06:58 PM

Tags for this Thread