# Thread: is there a way of simplifying this

1. ## 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. > 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```

3. > 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. While
(*power) *= 10;
is the same as
*power *= 10;

(*len)++;
is most definitely NOT the same as
*len++;

5. could you say *len += 1 and get the same result as (*len)++

6. Yes.