I want to count if is the number of the row on the left group to make the configuration acceptable by the procedures. Output -1 if there is no acceptable configuration. the procedures is left a(X) middle b(x+1) and right c(x+2). does anyone have a better solution than mine?
#include<stdio.h>
int main(void)
{
int chairs,a,b,c,result;
scanf("%d %d %d %d", &chairs,&a ,&b , &c);
for(int i=1; i<=chairs; i++)
{
result= (a*(i)) + (b*(i+1)) + (c*(i+2));
if(chairs == result)
{
printf("%d", i);
break;
}
else if(i == chairs && chairs != result)
printf("-1");
}
}
This is rather a math problem.
a * x + b * (x + 1) + c * (x + 2) = chair
a * x + b * x + b + c * x + 2 * c = chair
a * x + b * x + c * x = chair - b - 2 * c
x * (a + b + c) = chair - b - 2 * c
x = (chair - b - 2 * c) / (a + b + c)
This can be solved in 1 operation. No solution if a + b + c == 0
It boils down to a math question
where
if ( (a+b+c) == 0) return -1 ;
X = (Chairs - b - 2c) / (a+b+c) , Y = (Chairs - b - 2c) % (a+b+c)
if X > 0 && X <= Chairs && y == 0
return X ;
else
return -1 ;
Related
I needed a square root approximation in C so I looked up this post and got this following implementation:
float squareroot(float n)
{
float x = n;
float y = 1;
float e = 0.001; // Accuracy level
if (n == 0)
return 0;
while ((x - y) > e)
{
x = (x + y) / 2;
if (n == 0 || x == 0)
return 0;
y = n / x;
}
return x;
}
What is the time complexity of this?
Hint:
Observe that
(x[k+1] - √n)/(x[k+1] + √n) = (x[k] + n/x[k] - 2√n)/(x[k] + n/x[k] + 2√n)
= (x[k] - √n)²/(x[k] + √n)².
So by induction,
(x[k] - √n)/(x[k] + √n) = (x[0] - √n)^(2^k)/(x[0] + √n)^(2^k)
= (√n - 1)^(2^k)/(√n + 1)^(2^k).
From this we find the number of iterations after which the error is e:
k = lg(lg(e / (2√n - e)) / lg((√n - 1)/(√n + 1)).
(base-2 logarithm.)
I was given a problem to write a C program which would solve the equation ax2+bx+c=0, where a, b and c are coefficients with double type. Any of the coefficients may be zero. In this problem it is unclear to me how to handle the double variables.
Here is my code. As for now, I know that my program can't distinguish between two roots and infinitely many roots. It also doesn't detect the "linear equation situation". How can I make it detect an infinite number of solutions? I was also advised in the comments to calculate the root with the minus before the discriminant if b > 0 and then use the Viet's theorem. I understand that it is because it is always more accurate to sum two numbers. I also guess I should do the exact opposite with b < 0. But what if b == 0 ? In this case, the program will not do anything. Or should I just include b == 0 in b < 0 and have b <= 0 ?
#include <stdio.h>
#include <math.h>
#include <float.h>
int main() {
double a, b, c, x1, x2;
scanf("%lf", &a);
scanf("%lf", &b);
scanf("%lf", &c); // just reading variables
//ax^2+bx+c=0
if ((b * b - 4 * a * c) < 0) {
printf("no");
} else {
x1 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a); //calculating roots
x2 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
if ((fabs((a * x1 * x1 + b * x1 + c)) < DBL_EPSILON) & (fabs((a * x2 * x2 + b * x2 + c)) < DBL_EPSILON)) { //plugging the roots in
if (fabs((x1 - x2)) < DBL_EPSILON) { //checking if the roots are equal
printf("%lf", &x1); // if they are equal, we print only one of them
} else {
printf("%lf", &x1); // if they are not equal, we print both.
printf("\n %lf", &x2);
}
} else { // if there are no two valid roots
if ((fabs((a * x1 * x1 + b * x1 + c)) < DBL_EPSILON)) // we try to find one root.
printf("%lf", &x1);
if (fabs((a * x2 * x2 + b * x2 + c)) < DBL_EPSILON)
printf("%lf", &x2);
if ((fabs((a * x1 * x1 + b * x1 + c)) > DBL_EPSILON) & (fabs((a * x2 * x2 + b * x2 + c)) > DBL_EPSILON)) // if both of the plugged roots don't satisfy the equation
printf("no");
}
}
return 0;
}
Solve quadratic equation when coefficients may be 0
How can I make it detect an infinite number of solutions?
When a==0 && b == 0 && c == 0.
No DBL_EPSILON needed really anywhere in this code. See also #Eric Postpischil.
But what if b == 0 ?
if (b == 0) { // y = a*x*x + c
if (a) {
double dd = -c/a;
if (dd >= 0) {
double d = sqrt(d);
printf_roots("+/- roots", d,-d);
} else {
printf_roots("Complex roots", NAN, NAN); // Note NAN may not exist
}
} else if (c) { // y = 0*x*x + c, c != 0
printf_roots("No roots", NAN, NAN);
} else { // y = 0*x + 0
printf_roots("Infinite roots", -HUGE_VAL, HUGE_VAL);
}
Or should I just include b == 0 in b < 0 and have b <= 0 ?
Unless the coding goal requires a special output when b==0, I would only vector code on b==0 as a subtest when a==0 occurred.
if (a==0) {
if (b == 0) {
The quadric equation, like much FP code, can readily overflow and hit 0, both cases losing all precision.
Consider the code below: the unnecessary subtraction may cause overflow or truncation to 0 versus the second which may not. It is dependent on many things.
if ((b * b - 4 * a * c) < 0)
//
if (b * b < 4 * a * c)
Further, C allows various calculations to occur using wider math. Research FLT_EVAL_METHOD. Because of this, to prevent sqrt(value_less_than_0), code should calculate the discriminate and then test the object x that is going to be applied to sqrt(x).
//if ((b * b - 4 * a * c) < 0) {
// printf("no");
//} else {
// x1 = (-b + sqrt(b * b - 4 * a * c))
double discriminate = b * b - 4 * a * c;
if (discriminate < 0) {
printf("no");
} else {
double d = sqrt(discriminate);
x1 = (-b + d)
As to the idea of "calculate the root with the minus before the discriminant if b > 0 and then use the Viet's theorem", I'd suggest for improved retained precision the below which does not subtract like signed values.
double d = sqrt(discriminate);
// Note x1*x2 = c/a
if (b < 0) {
x2 = (-b + d)/(2*a);
x1 = c/a/x2;
} else {
x1 = (-b - d)/(2*a);
x2 = c/a/x1;
}
printf_roots("2 roots", x1, x2);
Notes on printf("%lf", &x1);. You are not compiling with all warnings enabled. Save time - enable them. Should be printf("%lf", x1); No &.
Further double is floating point. For FP code development use "%e", "%a" or"%g" to full see significant information.
printf("%g\n", some_double);
// or better
printf("%.*e\n", DBL_DECIMAL_DIG -1, some_double);
Since division by zero is not allowed, you have to split the problem into 4 cases :
a != 0:
this is case you treated in your code.
a == 0 && b != 0 :
This is a linear equation where the solution is x = -c/b
a == 0 && b == 0 && c != 0 : There's no possible value for x.
In this last case, a, b and c are equals to 0 : there's infinitly many solutions for x.
EDIT: comparisons with epsilon removed since they seem to be useless
There are some problems in your code:
you should check the return values of scanf() to avoid undefined behavior on invalid input.
you should use local variables for intermediary results to improve code readability
your printf statements are incorrect: you should pass the values of the double variables instead of their addresses: printf("%lf", &x1); should read:
printf("%f", x1);
Regarding the degenerate cases, you should just test those before trying to resolve the second degree equation.
Here is a corrected version:
#include <stdio.h>
#include <math.h>
int main() {
double a, b, c, delta, x1, x2;
if (scanf("%lf%lf%lf", &a, &b, &c) != 3) {
printf("invalid input\n");
return 1;
}
if (a == 0) {
// not a quadratic equation
if (b != 0) {
printf("one solution: %g\n", -c / b);
} else {
if (c != 0) {
printf("no solution\n");
} else {
printf("all real values are solutions\n");
}
}
} else {
delta = b * b - 4 * a * c;
if (delta < 0) {
printf("no real solution\n");
} else
if (delta == 0) {
printf("one double solution: %g\n", -b / (2 * a));
} else {
x1 = (-b + sqrt(delta)) / (2 * a);
x2 = (-b - sqrt(delta)) / (2 * a);
printf("two solutions: %g, %g\n", x1, x2);
}
}
return 0;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
My code is supposed to calculate the total combinations. For paying cash between 1-500 dollars using these coins: 1, 2, 5, 10, 20, 50, 100, 200. But it doesn't calculate it right. what have I done wrong?
You can assume that the input is correct and you can only use loops and if statements. You may not use recursion.
int pr, a, b, c, d, e, f, g,h, poss = 0;
printf_s("What is the amount that you like to check? (or press '0' to exit)\n");
scanf_s("%d", &pr);
for (a = 0; a <= pr; a++)
{
for (b = 0; b <= (pr/2); b++)
{
for (c = 0; c <= (pr /5); c++)
{
for (d = 0; d <= (pr /10); d++)
{
for (e = 0; e <= (pr /20); e++)
{
for (f = 0; f <= (pr / 50); f++)
{
for (g = 0; g <= (pr / 100); g++)
{
for (h = 0; h <= (pr/200); h++)
{
if (1 * a + 2 * b + 4 * c + 10 * d + 20 * e + 40 * f + 100 * g + h * 200 == pr)
poss += 1;
}
}
}
}
}
}
}printf_s("The number of possibilities is: %d.\n", poss);
}
When 5 is entered the correct number of perms is reported but expanding the code prints the wrong values. Because this line
if (1 * a + 2 * b + 4 * c + 10 * d + 20 * e + 40 * f + 100 * g + h * 200 == pr)
has the wrong denominations. It should be
if (1 * a + 2 * b + 5 * c + 10 * d + 20 * e + 50 * f + 100 * g + h * 200 == pr)
You should also move the line
printf_s("The number of possibilities is: %d.\n", poss);
outside of the loops.
Your final printf needs to be out of the loops
for (a = 0; a <= pr; a++)
{
for (b = 0; b <= (pr/2); b++)
{
for (c = 0; c <= (pr /5); c++)
{
for (d = 0; d <= (pr /10); d++)
{
for (e = 0; e <= (pr /20); e++)
{
for (f = 0; f <= (pr / 50); f++)
{
for (g = 0; g <= (pr / 100); g++)
{
for (h = 0; h <= (pr/200); h++)
{
if (1 * a + 2 * b + 4 * c + 10 * d + 20 * e + 50 * f + 100 * g + h * 200 == pr)
poss += 1;
}
}
}
}
}
}
}
}
printf("The number of possibilities is: %d.\n", poss);
As mentioned in Weather Vane answer, OP is using some wrong multipliers in the inner condition (4 and 40 instead of 5 and 50).
It's worth noting that, even with this brute force approach, we can save some CPU time by avoiding unnecessary calculations inside the (way too nested) loops and limiting the ranges of those loops to a smaller extent.
Consider the following refactorization:
#include <stdio.h>
int number_of_possibilities(int price)
{
int poss = 0;
// It takes less time to consume the bigger pieces earlier
for (
// 'a' represent the sum of the values of 200$ pieces, not the number of 200$
// pieces, which is 'a / 200'
int a = 0; a <= price;
// add the value of a single 200$ piece to move forward
a += 200 )
{
for ( int b = 0,
// 'dif_b' is what is left from the price, once the 200$ pieces are counted
dif_b = price - a;
// we don't need to iterate from 0 to 'price', but only to what is left
b <= dif_b; b += 100 )
{
// 'dif_c' is what is left once the 100$ and 200$ pieces counted so far are
// subctracted from the original price. The same holds for the inner loops
for ( int c = 0, dif_c = dif_b - b; c <= dif_c; c += 50 )
{
for ( int d = 0, dif_d = dif_c - c; d <= dif_d; d += 20 )
{
for ( int e = 0, dif_e = dif_d - d; e <= dif_e; e += 10 )
{
for ( int f = 0, dif_f = dif_e - e; f <= dif_f; f += 5 )
{
for ( int g = 0, dif_g = dif_f - f; g <= dif_g; g += 2 )
{
// now that only the 1$ coins are left to consider, we can avoid another inner
// loop and just realize that we need exactly 'dif_g - g' 1$ coins to pay the
// full price, so there is one and only one possible combination.
++poss;
}
}
}
}
}
}
}
return poss;
}
int main(void)
{
printf(" i number of possibilities\n\n");
for ( int i = 0; i < 501; ++i )
{
printf("%4d %16d\n", i, number_of_possibilities(i));
}
return 0;
}
Which gives the following:
i number of possibilities
0 1
1 1
2 2
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 11
...
99 4366
100 4563
101 4710
...
498 6159618
499 6224452
500 6295434
Executed in less then 2 seconds on an old Atom N270 at 1.6 GHz...
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
I am trying to write a program to perform point operations on a elliptic curve in a prime field I am using the standard formulaes for point additions and doubling in my code and these operations are performed by functions that are called but I am getting output for certain points but not all so please help me to fix the problem that are present in this code.
structure point_multiply(int x, int y, int k )
{
int xk;
int yk,m;
xk=x;
yk=y;
m=1;
int xL,yL,s,e;
e=findInverse((2*yk),211);
if((((3*(xk*xk))*e)% 211)>0)
{s = (((3*(xk*xk))*e)% 211);
}
else
s=(((3*(xk*xk))*e)% 211)+ 211;
if((((s*s)- (2*xk)) % 211)>0)
{xL=(((s*s)- (2*xk)) % 211);
}
else
xL=(((s*s)- (2*xk)) % 211) + 211;
if(((-yk+ s*(xk-xL)) % 211) > 0)
yL=(-yk+ s*(xk-xL)) % 211;
else
yL=(-yk+ s*(xk-xL)) % 211 + 211;
xk=xL;
yk=yL;
m=m+1;
while(k>m)
{
sn=point_addition(xk,yk,x,y);
xk=sn.a;
yk=sn.b;
m++;
}
s1.a=xk;
s1.b=yk;
return s1;
}
structure point_addition(int x1, int y1, int x2, int y2)
{
int s,xL,yL;
if((x1-x2)!=0)
{
if ( x1 == 0 && y1 == 0 )
{
xL = x2;
yL = y2;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( x2 == 0 && y2 == 0 )
{
xL = x1;
yL = y1;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( y1 == -y2 )
{
xL = yL = 0;
s7.a=xL;
s7.b=yL;
return s7;
}
l=findInverse((x1-x2),211);
if ((((y1-y2)*l) % 211)>=0)
s=((((y1-y2)*l) % 211));
else
s=(((y1-y2)*l) % 211) + 211;
if ((((s*s)-(x1+x2)) % 211)>0)
xL= (((s*s)-(x1+x2)) % 211) ;
else
xL= (((s*s)-(x1+x2)) % 211) + 211;
if(((-y1+s*(x1-xL)))>=0)
yL= ((-y1+s*(x1-xL)) % 211);
else
yL= ((-y1+s*(x1-xL)) % 211) + 211;
}
else
{
xL= 0 ;
yL= 0;
}
s7.a= xL;
s7.b= yL;
return s7 ;
}
int findInverse(int a, int b)
{
int x[3];
int y[3];
int quotient = a / b;
int remainder = a % b;
x[0] = 0;
y[0] = 1;
x[1] = 1;
y[1] = quotient * -1;
int i = 2;
for (; (b % (a%b)) != 0; i++)
{
a = b;
b = remainder;
quotient = a / b;
remainder = a % b;
x[i % 3] = (quotient * -1 * x[(i - 1) % 3]) + x[(i - 2) % 3];
y[i % 3] = (quotient * -1 * y[(i - 1) % 3]) + y[(i - 2) % 3];
}
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
if(x[(i - 1) % 3]<0)
return x[(i - 1) % 3]+211;
else
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
return x[(i - 1) % 3];
}
Edited and added main c code which uses these function to perform elliptic curve cryptography
int main()
{
int y,z=0,x=2,i[200],j[200],h=0,g,k;
while(x<200)
{
y=sqrt((x*x*x)-4);
z=modulo(y,211);
if(z!=0)
{
i[h]=x;
j[h]=z;
s[h].a=i[h];
s[h].b=j[h];
s[h+1].a=i[h];
s[h+1].b=(211 - j[h]);
printf("\nh=%d X= %d Y= %d \nh=%d X= %d Y= %d",h,s[h].a,s[h].b,h+1,s[h+1].a,s[h+1].b);
h=h+2;
}
x++;
}
printf("The total no of points we have on our elliptic curve for cryptography is %d",h-1);
x=5;
y=11;
printf("\n %d %d\n",x,y );
printf("\nEnter A number between 0 and the private key");
scanf("%d",&k);
s2=point_multiply(x,y,k);
printf("\n The public key is \n %d %d \n ",s2.a,s2.b );
printf("Enter a RANDOM number to generate the cipher texts");
scanf("\n%d",&g);
s3= point_multiply(x,y,g);
s4=point_multiply(s2.a,s2.b,g );
label:
printf("\n Enter a number to send");
scanf("%d",&h);
s6=point_addition(s4.a,s4.b,s[h].a,s[h].b);
printf("The points to be sent are X= %d Y=%d",s[h].a,s[h].b);
printf(" \n X= %d Y=%d\n X = %d Y= %d ",s3.a,s3.b,s6.a,s6.b);
//RECIEVER
s8=point_multiply(s3.a,s3.b,k);
s9=point_addition((s8.a) ,-((s8.b)%211),s6.a,s6.b);
printf(" The decrypted points are \n %d %d",s9.a,s9.b);
printf("\n If you have more no to send press 1 else press 0");
scanf("\n %d", &x1);
if(x1==1)
goto label;
else
return 0;
}
s1, s2, s3 etc are structures which hold a 2 integers which act as x and y co-ordinates
I am getting output by entering k=3,g=4, h=5 and many other cases mostly with small numbers but not for larger numbers. What could be wrong with the code?
Further edit: I guess that normal square root method is not applicable to find square roots of a modular no?.. Please tell me how to find the modular square root of a no?