Error in C program to find integer triplets (x,y,z) such that n^x + n^y = n^z for given range of n - c

I want to make a C program compatible for DEV-C++ 4.9.9.2 to find integer triplets (x,y,z) such that for any integer n the equation n^x + n^y = n^z holds where n is any integer in the range [a,b]. The c program would have an input of only a and b and find such possible triplets.
The code that I wrote isn't working. What's the error in it?
for (n = a ; n <= b ; n++) {
for (x = a ; x < b ; x++) {
for (y = a ; y < b ; y++) {
for (z = a ; z = b ; z++) {
c = pow(n, x);
d = pow(n, y);
e = pow(n, z);
f = c + d;
if (e = f) {
printf("(%d , %d , %d) : %d", x,y,z,n);
}
}
}
}
}
I'm a novice in C.

C correction
Try changing
if (e=f)
into
if (e==f)
The first does assignment, the second tests equality.
(Note that you may also get overflow if the numbers tested get larger than your datatype.)
Maths approach
If y==x, then:
n^x + n^x = n^z
2n^x = n^z
=> n == 0 or n == 2
Now, assume y>x and n!=0.
n^x + n^y = n^z
n^x ( 1 + n^(y-x)) = n^z
=> 1+n^(y-x) = n^(z-x)
=> 1 = 0 ( modulo n)
=> impossible unless n==0 (in which case any x,y works) or n==1 (which does not work)
So this equation has solutions for any x,y if n==0.
Otherwise, the only solutions are with n==2, x==y and z=x+1.

Change
if (e = f)
to
if (e == f)
The first one assigns f to e, enable compiler warnings for such mistakes. The second one equates the LHS to the RHS.
Secondly, assuming your program is a brute force, i.e., loops for all values of x, y and z, you might want to change this statement:
for (z = a ; z = b ; z++)
to
for (z = a ; z < b ; z++)

Your implementation is O(n^4) , actually it can be done in O(n^3) .Here is the code
for (n = a ; n <= b ; n++) {
for (x = a ; x < b ; x++) {
for (y = a ; y < b ; y++) {
{
c = pow(n, x);
d = pow(n, y);
f = c + d;
e = pow(f,1.0/n);
if (e >= a && e < b) {
z = e;
printf("(%d , %d , %d) : %d", x,y,z,n);
}
}
}
}
}

Related

What does the variable D do inside the while in this Bresenham's line drawing algorithm?

I've found this Generalized Bresenham's Line Drawing Algorithm and I'm having a hard time understanding what the while is doing here.
Any help is greatly appreciated.
the code:
#define sign(x) ((x > 0)? 1 : ((x < 0)? -1: 0))
x = x1;
y = y1;
dx = abs(x2 - x1);
dy = abs(y2 - y1);
s1 = sign(x2 - x1);
s2 = sign(y2 - y1);
swap = 0;
if (dy > dx) {
temp = dx;
dx = dy;
dy = temp;
swap = 1;
}
D = 2*dy - dx;
for (i = 0; i < dx; i++) {
display_pixel (x, y);
while (D >= 0) {
D = D - 2*dx;
if (swap)
x += s1;
else
y += s2;
}
D = D + 2*dy;
if (swap)
y += s2;
else
x += s1;
}
D is the scaled distance from the line to the candidate x, y coordinate.
Better: D is scaled difference of the distance from the line to the candidates x+1, y+0 and x+1, y+1.
That is, as x increments, the sign of D indicates should the closer y increment by 0 or 1?
(The role of x, y interchanges depending on which octant the algorithm is applied.)
I expected while (D >= 0) { as if (D >= 0) {. Bresenham's line algorithm
Note that OP's code is subject to overflow in abs(x2 - x1) and 2*dy - dx. Alternates exist that do not rely on wider math.

How to write on a file from Top to Bottom in C

I would like to ask if its possible to write on a file from top to bottom?
The current code below will flip and image Vertically.
This uses left to right writing to a file.
On the other hand, I am having problem on how would I do the flip image Horizontally if I follow the left to right pattern on writing to a file.
Note: I have other option here, which is to swap lines from top to bottom.
Who knows maybe there's a way to follow the Vertical Flip pattern.
I would appreciate any help you guys can give. Thanks.
//Flip Vertically
for(y = WIDTH-1 ; y >= 0 ; y--) {
for(x = 0 ; x < HEIGHT; x++) {
p = (unsigned char *)datap + ((WIDTH) * y * 3) + (x * 3);
// output pixel
if(fwrite(p, sizeof(char), 3, outfp) != 3) {
cleanUpBeforeExit(infp, outfp, datap, E_FILE_WRITE_ERROR);
}
}
}
Beware that the terms that you use are very ambiguous. Flip vertically, flip horizontally can be understood two ways, as can top-to-bottom when speaking of a file.
Hence I'll give a general answer.
Assume you write the pixels in the usual scanning order, top row first, left pixel first, i.e. by addressing Image[Column + Row * Pitch] in a double loop (outer on Row, inner on Column). You can also reverse the loop traversal order.
Then you will obtain a left-right mirroring (pixels move horizontally) by writing Image[(Width - 1 - Column) + Row * Pitch], and a top-bottom mirroring (pixels move vertically) with Image[Column + (Height - 1 - Row) * Pitch].
You can combine the two modifications to achieve a 180° rotation.
When writing to a file would normally write data from start-of-file towards end-of-file. Writing in any other order will in most cases make your program more complicated and give worse performance.
So what you need is to access your data in the correct order depending on how you want to flip the data.
Something like:
#include <stdio.h>
#define WIDTH 2
#define HEIGHT 3
void print_element(char* p)
{
// Here I just print to stdout but you can just save it to a file
printf("%c %c %c ", *p, *(p+1), *(p+2));
}
int main()
{
char data[3 * HEIGHT][3 * WIDTH] = {{'a', 'b', 'c', 'd', 'e', 'f'},
{'g', 'h', 'i', 'j', 'k', 'l'},
{'m', 'n', 'o', 'p', 'q', 'r'}};
char* datap = (char*)data;
char* p;
printf("Normal\n");
for(int y = 0; y < HEIGHT; y++)
{
for(int x = 0 ; x < WIDTH; x++)
{
p = datap + ((WIDTH) * y * 3) + (x * 3);
print_element(p);
}
printf("\n");
}
printf("\nFlip horizontal\n");
for(int y = HEIGHT-1 ; y >= 0 ; y--)
{
for(int x = 0 ; x < WIDTH; x++)
{
p = datap + ((WIDTH) * y * 3) + (x * 3);
print_element(p);
}
printf("\n");
}
printf("\nFlip vertical\n");
for(int y = 0; y < HEIGHT; y++)
{
for(int x =WIDTH-1; x >= 0; x--)
{
p = datap + ((WIDTH) * y * 3) + (x * 3);
print_element(p);
}
printf("\n");
}
printf("\nFlip both\n");
for(int y = HEIGHT-1 ; y >= 0 ; y--)
{
for(int x = WIDTH-1; x >= 0; x--)
{
p = datap + ((WIDTH) * y * 3) + (x * 3);
print_element(p);
}
printf("\n");
}
return 0;
}
This will produce:
Normal
a b c d e f
g h i j k l
m n o p q r
Flip horizontal
m n o p q r
g h i j k l
a b c d e f
Flip vertical
d e f a b c
j k l g h i
p q r m n o
Flip both
p q r m n o
j k l g h i
d e f a b c

Optimizing a nested loop in C

I have a nested loop to find all possible combinations of numbers between 1 and x in groups of 4, where a < b < c < d.
A method is called as each group is discovered to do a simple equivalency test on the sum of those numbers.
The loop does work and produces expected output (1 set of numbers for this particular x), however it takes 12+ seconds to find this answer and another ~5 to test the remaining possibilities, which is definitely bad, considering the x values are < 1000.
I tried having the outer loop iterate a < x - 3 times, the b loop b < x - 2 times, down to d < x times which didn't make a noticeable difference.
What would be a better approach in changing this loop?
for (a = 1; a < x; a++) {
for (b = a + 1; b < x; b++) {
for (c = b + 1; c < x; c++) {
for (d = c + 1; d < x; d++) {
check(a, b, c, d);
}
}
}
}
With such a deep level of nesting, any early exit you can introduce - particularly at the outer loops - could net big gains.
For example, you write that check is testing a + b + c + d == x && a * b * c * d == x - so you can compute the intermediate sum and product, and break when you encounter numbers that would make any selection of later numbers impossible.
An example:
for (a = 1; a < x; a++) {
for (b = a + 1; b < x; b++) {
int sumAB = a + b;
if (sumAB + sumAB > x) break;
int prodAB = a * b;
if (prodAB * prodAB > x) break;
for (c = b + 1; c < x; c++) {
int sumABC = sumAB + c;
if (sumABC + c > x) break;
int prodABC = prodAB * c;
if (prodABC * c > x) break;
for (d = c + 1; d < x; d++) {
int sumABCD = sumABC + d;
if (sumABCD > x) break;
if (sumABCD != x) continue;
int prodABCD = prodABC * d;
if (prodABCD > x) break;
if (prodABCD != x) continue;
printf("%d, %d, %d, %d\n", a, b, c, d);
}
}
}
}
This is just an example - you can constrain all the checks here further (e.g. make the first check be sumAB + sumAB + 3 > x). The point is to focus on early exits.
I added a counter for each loop, counting how many times it was entered, and tried your version and my version, with x = 100. My version has orders of magnitude less loop entries:
No early exits: 99, 4851, 156849, 3764376
With early exits: 99, 4851, 1122, 848

For loop and While loop to select values in C

Could someone help me to look at the code I wrote in C? It can generate numbers, but the if condition looks like wrong, but I donot know how to fix it.
I need to get some n random values with distribution and these values are in a special intervals, so I use for loop like below:
n=10; mu=2; mu_plus=3; p=0.2;
for(i=1; i<=n; i++)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
Z[i]=z;
Z_plus[count]=z_p;
}
printf("%d %lf %lf\n", i, Z[i], Z_plus[i]);
}
Where gasdev() is a function for generating random value with a standard normal distribution, Z and Z_plus are 1*n vectors. The results are mess, so I think that the IF condition must be wrong. Could any one could help me? Thank you.
I also tried the While loop.
while(count < n)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
count++;
Z[count]=z;
Z_plus[count]=z_p;
}
printf("%d %lf\n",count, Z[count]);
if (count >n) break;
}
It can print out normally, but occurs an error at the end.
Thank you!
The error here is that you always increment i as part of the for loop so that if z is outside the range of the bracket set, you do not put any value into the Z array. You do not specify count so was that supposed to be i or not?
n=10; mu=2; mu_plus=3; p=0.2;
for(i=1; i<=n; i++)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
Z[i]=z;
Z_plus[count]=z_p; // Should this be Z_plus[i] ??
}
// Note that if outside of bracket no value put in Z[i]
// This makes Z[i] and Z_plus[i] garbage
printf("%d %lf %lf\n", i, Z[i], Z_plus[i]);
}
Your while loop is not correct either as it increments count when it is n-1 and tries to process Z[n] when it appears that you must have defined it as an array of size n (max index is n-1). Also the print needs to be inside the if not outside.
while(count < n)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
// This allows count == n which overflows the buffer.
count++;
Z[count]=z;
Z_plus[count]=z_p;
}
// This should be inside the bracket not outside
printf("%d %lf\n",count, Z[count]);
// This is not needed since it will exit the while at count == n
if (count >n) break;
}
correct code would be
count = 0;
while(count < n)
{
x1 = gasdev(&idum);
x2 = gasdev(&idum);
z = sqrt(1-p*p)*x1 + p*x2 + mu;
z_p= x2 + mu_plus;
if (z > 2.17 || z<-2.17)
{
Z[count]=z;
Z_plus[count]=z_p;
printf("%d %lf\n",count, Z[count]);
count++;
}
}

Pollard Rho factorization method implementation in C

Can anyone help me out with the pollard rho implementation? I have implemented this in C. It's working fine for numbers upto 10 digits but it's not able to handle greater numbers.
Please help me out to improve it to carry out factorization of numbers upto 18 digits . My code is this:
#include<stdio.h>
#include<math.h>
int gcd(int a, int b)
{
if(b==0) return a ;
else
return(gcd(b,a%b)) ;
}
long long int mod(long long int a , long long int b , long long int n )
{
long long int x=1 , y=a ;
while(b>0)
{
if(b%2==1) x = ((x%n)*(y%n))%n ;
y = ((y%n)*(y%n))%n ;
b/=2 ;
}
return x%n ;
}
int isprimes(long long int u)
{
if(u==3)
return 1 ;
int a = 2 , i ;
long long int k , t = 0 , r , p ;
k = u-1 ;
while(k%2==0)
{ k/=2 ; t++ ; }
while(a<=3) /*der are no strong pseudoprimes common in base 2 and base 3*/
{
r = mod(a,k,u) ;
for(i = 1 ; i<=t ; i++)
{
p = ((r%u)*(r%u))%u ;
if((p==1)&&(r!=1)&&(r!=(u-1)))
{ return 0 ; }
r = p ;
}
if(p!=1)
return 0 ;
else
a++ ;
}
if(a==4)
return 1 ;
}
long long int pol(long long int u)
{
long long int x = 2 , k , i , a , y , c , s;
int d = 1 ;
k = 2 ;
i = 1 ;
y = x ;
a = u ;
if(isprimes(u)==1)
{
return 1;
}
c=-1 ;
s = 2 ;
while(1)
{
i++;
x=((x%u)*(x%u)-1)% u ;
d = gcd(abs(y-x),u) ;
if(d!=1&&d!=u)
{ printf("%d ",d);
while(a%d==0) { a=a/d; }
x = 2 ;
k = 2 ;
i = 1 ;
y = x ;
if(a==1)
{ return 0 ; }
if(isprimes(a)!=0)
{ return a ; }
u=a ;
}
if(i==k)
{y = x ; k*=2 ; c = x ;} /*floyd cycle detection*/
if(c==x)
{ x = ++s ; }
}
return ;
}
int main()
{
long long int t ;
long long int i , n , j , k , a , b , u ;
while(scanf("%lld",&n)&&n!=0)
{ u = n ; k = 0 ;
while(u%2==0)
{ u/=2 ; k = 1 ; }
if(k==1) printf("2 ") ;
if(u!=1)
t = pol(u) ;
if(u!=1)
{
if(t==1)
{ printf("%lld",u) ; }
else
if(t!=0)
{ printf("%lld",t) ; }
}
printf("\n");
}
return 0;
}
sorry for the long code ..... I am a new coder.
When you're multiplying two numbers modulo m, the intermediate product can become nearly m^2. So if you use a 64-bit unsigned integer type, the maximal modulus it can handle is 2^32, if the modulus is larger, overflow may happen. It will be rare when the modulus is only slightly larger, but that makes it only less obvious, you cannot rely on being lucky if the modulus allows the possibility of overflow.
You can gain a larger range by a factor of two if you choose a representative of the residue class modulo m of absolute value at most m/2 or something equivalent:
uint64_t mod_mul(uint64_t x, uint64_t y, uint64_t m)
{
int neg = 0;
// if x is too large, choose m-x and note that we need one negation for that at the end
if (x > m/2) {
x = m - x;
neg = !neg;
}
// if y is too large, choose m-y and note that we need one negation for that at the end
if (y > m/2) {
y = m - y;
neg = !neg;
}
uint64_t prod = (x * y) % m;
// if we had negated _one_ factor, and the product isn't 0 (mod m), negate
if (neg && prod) {
prod = m - prod;
}
return prod;
}
So that would allow moduli of up to 2^33 with a 64-bit unsigned type. Not a big step.
The recommended solution to the problem is the use of a big-integer library, for example GMP is available as a distribution package on most if not all Linux distros, and also (relatively) easily installable on Windows.
If that is not an option (really, are you sure?), you can get it to work for larger moduli (up to 2^63 for an unsigned 64-bit integer type) using Russian peasant multiplication:
x * y = 2 * (x * (y/2)) + (x * (y % 2))
so for the calculation, you only need that 2*(m-1) doesn't overflow.
uint64_t mod_mult(uint64_t x, uint64_t y, uint64_t m)
{
if (y == 0) return 0;
if (y == 1) return x % m;
uint64_t temp = mod_mult(x,y/2,m);
temp = (2*temp) % m;
if (y % 2 == 1) {
temp = (temp + x) % m;
}
return temp;
}
Note however that this algorithm needs O(log y) steps, so it's rather slow in practice. For smaller m you can speed it up, if 2^k*(m-1) doesn't overflow, you can proceed in steps of k bits instead of single bits (x*y = ((x * (y >> k)) << k) + (x * (y & ((1 << k)-1)))), which is a good improvement if your moduli are never larger than 48 or 56 bits, say.
Using that variant of modular multiplication, your algorithm will work for larger numbers (but it will be significantly slower). You can also try test for the size of the modulus and/or the factors to determine which method to use, if m < 2^32 or x < (2^64-1)/y, the simple (x * y) % m will do.
You can try this C implementation of Pollard Rho :
unsigned long long pollard_rho(const unsigned long long N) {
// Require : a composite number N, not a square.
// Ensure : res is a non-trivial factor of N.
// Option : define a timeout, define a rand function.
static const int timeout = 18;
static unsigned long long rand_val = 2994439072U;
rand_val = (rand_val * 1025416097U + 286824428U) % 4294967291LLU;
unsigned long long res = 1, a, b, c, i = 0, j = 1, x = 1, y = 1 + rand_val % (N - 1);
for (; res == 1; ++i) {
if (i == j) {
if (j >> timeout)
break;
j <<= 1;
x = y;
}
a = y, b = y;
for (y = 0; a; a & 1 ? b >= N - y ? y -= N : 0, y += b : 0, a >>= 1, (c = b) >= N - b ? c -= N : 0, b += c);
y = (1 + y) % N;
for (a = N, b = y > x ? y - x : x - y; (a %= b) && (b %= a););
res = a | b;
}
return res;
}
Otherwise there is a pure C quadratic sieve which factors numbers from 0 to 300-bit.

Resources