Finding which Pythagorean triple has the smallest angle - c

Information: a being the length of the shortest leg of a right triangle and b being the length of the other leg, the larger the difference between a and b the smaller the angle. That is:
the triple (3, 4, 5) has a difference of 4-3=1
the triple (5, 12, 13) has a difference of 12-5=7
Therefore the smallest angle would be in the triple (5, 12, 13)
I'm writing a program that compares all of the pythagorean triples defined in a range and prints the triple with the smallest angle. What I have so far is not working and I have no idea where I can go from here.
#include <stdio.h>
int smallest(int a, int b) {
int difference = b - a;
return 0;
}
int main() {
int a = 0, b = 0, c = 0, n, counter = 1, i = 0;
printf("Please Enter a Positive Integer: \n");
scanf("%d", &n);
for (c = 0; c < n; c++) {
for (b = 0; b < c; b++) {
for (a = 0; a < b; a++) {
if (a * a + b * b == c * c ) {
printf("%d:\t%d %d %d\n", counter++, a, b, c);
}
}
}
i = counter - 1;
}
printf ("The difference is %d\n", smallest(a, b));
printf ("There are %d Pythagorean Triples in this range.\n", i);
return 0;
}
The program just prints the difference is 0
what I am looking for the program to print is, for the example above "The triangle with the smallest angle is (5, 12, 13)"
I know I have to sort the differences and compare them but this is all I have so far, any tips?

Are you sure your 'information' is right? Because triple (30, 40, 50) has a difference of 10 and just the same angle as (3, 4, 5).
You don't have to sort, you have to remember difference/angle/whatever you minimize, as already mentioned in comments. Also, you have to remember values of 'minimal' (a,b,c) to print them later. Something like this:
//...
if (a * a + b * b == c * c ) {
printf("%d:\t%d %d %d\n", counter++, a, b, c); //if you use ++counter instead, you won't need i ;)
if(minDifference < b-a){ //Don't be afraid of variables with long names
minA = a; minB = b; minC = c; minDifference = b-a;
}
}
//...
printf("The triangle with the smallest difference is (%d, %d, %d)", minA, minB, minC);

Your smallest-code returns 0 in every case. Are you sure you don't want to return difference instead (or even b-a)?
int smallest(int a, int b) {
return b-a;
}

Related

Must print a numerical sequence 15, 12, 24, 21, 42, 39, 78, 75, 150, 147

As I see it the numerical sequence consists of 2 separate sequences. This is the code that I have so far. I am not sure if you must use a while or a for loop. I am fairly new at coding so if someone please could help me.
if the entered value is 10 it must give the first 10 terms of the sequence, and if I enter 5 it must give me the first 5 terms of the sequence.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int a, n = 1, t, y = 1; // First Numerical Sequence
int b, m = 2, s, x = 2; // Second Numerical Sequence
int d, r, z; // Extra
printf("Enter A Tn : ");
scanf(" %d", &z);
printf("\n");
while (n <= z) {
a = 15;
r = pow(2, n - y);
d = (9 * (r - 1)) / (2 - 1);
t = a + d;
printf("%d\n", t);
n += 2;
y++;
}
while (m <= z) {
b = 12;
r = pow(2, m - x);
d = (9 * (r - 1)) / (2 - 1);
s = b + d;
printf("%d\n", s);
m += 2;
x++;
}
printf("\n");
return 0;
}
This will get the job done.
#include <stdio.h>
int main(){
int val,ic; //iteration count, will print ic*2 number
scanf("%d %d",&val,&ic);
for(int i = 0;i<ic;i++){
printf("%d ",val);
val-=3;
printf("%d ",val);
val*=2;
}
printf("\n");
}
How to compile & run:
C:\Users\stike\Desktop>rem assume you saved it in a.c
C:\Users\stike\Desktop>gcc -o a a.c
C:\Users\stike\Desktop>a
15
5
15 12 24 21 42 39 78 75 150 147
If you want to print the same sequence starting from 15 and o till a certain number which the user inputs, you can follow the following code.
Hope you understood the sequence pattern when a number is given it is printed and reduce the number by 3, then it is printed and then twice the number and printed, and again reduce by 3, likewise, it flows on.
#include <stdio.h>
int main() {
int endNum;
int beginNum = 15;
printf("Enter the end: ");//(lineA) here we initialize the variables with beginNum as 15
scanf("%d", &endNum); //(Line B) let the user to input endNum of the sequence,in the example it is 147
while ((beginNum-3) <= endNum) { // checks the condition
printf("%d ", beginNum);
if(beginNum==endNum) return 0; //check whether you print the end number.
beginNum -= 3; // reduce by 3
printf("%d ", beginNum);
beginNum *= 2; // multiply by 2
}
return 0;
}
if you don't need to user input a endNum just initialize the value 147 to variable endNum.
And delete the lines A and B.
Here's another approach using static variables
#include <stdio.h>
int next(void) {
static int last, n = 0;
if (n++ == 0) return last = 15; // 1st element of sequence
if (n % 2) return last = last * 2; // odd elements
return last = last - 3; // even elements
}
int main(void) {
for (int k = 0; k < 10; k++) {
printf("%d ", next());
}
puts("");
return 0;
}

Finding GCD using divison method in C

So I wanted to write a function to calculate the Gcd or HCF of two numbers using the Divison method.This is my code:
#include <stdio.h>
#include <stdlib.h>
void gcd(int x, int y)
{
int g,l;
if (x >= y)
{
g = x;
l = y;
}
else
{
g = y;
l = x;
}
while (g % l != 0)
{
g = l;
l = g % l;
}
printf("The GCD of %d and %d is %d", x, y, l);
}
int main(void)
{
gcd(8, 3);
return 0;
}
I am getting no output with this(error?): Process returned -1073741676 (0xC0000094)
Is there a problem with my loop?
In:
g = l;
l = g % l;
the assignment g = l loses the value of g before g % l is calculated. Change it to:
int t = g % l;
g = l;
l = t;
I use this loop while to find the gcd of two numbers like this:
void gcd(int x, int y)
{
int k=x,l=y;
if(x>0&&y>0)
{
while(x!=0&&y!=0)
{
if(x>y)
{
x=x-y;
}
else
{
y=y-x;
}
}
}
printf("\nThe GCD of %d and %d is %d", k, l, x);
}
int main(void)
{
gcd(758,306);
return 0;
}
Examples:
Input:
x=758 , y=306
x=27 , y=45
x=3 , y=8
Output:
printf("\nThe GCD of 758 and 306 is 2");
printf("\nThe GCD of 27 and 45 is 9");
printf("\nThe GCD of 3 and 8 is 1");
First of all, take into account that you are exchanging the numbers when x >= y which means that you try to put in x the smaller of the two. For GDC, there's no need to do
this, as the remainder of a division by a bigger number is always the original number, so if you have the sequence 3, 8, the first remainder will be 3, and the numbers switch positions automatically as part of the algorithm. So there's no need to operate with g (I guess for greater) and l (for lesser) so you can avoid that.
#include <stdio.h>
#include <stdlib.h>
void gcd(int x, int y)
{
int g,l;
if (x >= y)
{
g = x;
l = y;
}
else
{
g = y;
l = x;
}
Then, in this second part (the loop part) you have to take into account that you are calculating g % l twice in the same loop run (this is not the Euclides' algorithm).
while (g % l != 0)
{
g = l;
l = g % l;
}
You should better use a new variable r (for remainder, but I should recommend you to use longer, descriptive names) so you have always an idea of what the variable holds.
int r;
while ((r = g % l) != 0) {
g = l;
l = r;
}
you see? I just do one division per loop, but you make a l = g % l; which modifies the value of l, making you go through two iterations of the loop in one.
The final program is:
#include <stdio.h>
#include <stdlib.h>
int gcd(int greater, int lower)
{
int remainder;
while ((remainder = greater % lower) != 0) {
printf("g=%d, l=%d, r=%d\n", greater, lower, remainder);
greater = lower;
lower = remainder;
}
return lower; /* remember that remainder got 0 in the last loop */
}
int main(void)
{
int x = 6, y = 8;
printf("The GCD of %d and %d is %d\n",
x, y, gcd(x, y));
printf("The GCD of %d and %d is %d\n",
y, x, gcd(y, x));
return EXIT_SUCCESS;
}
(I have added a trace printf in the gcd() loop to show how the variables are changing, and both calculations ---changing the parameter values--- to show what I said above about the automatic change in order. Also, it's better to use the gcd() as a function that returns the value, and let main() decide if it wants to print results, or use the value for something else.
Enjoy it!! :)

c language ask a triangle formula

Write a program that outputs the length of the sides of the possible triangle and the number of triangles, when you want to create a triangle by inputting the sum of the lengths of the three sides of the triangle.(the three sides are integer variables.)
(the sum of the lengths of the two sides of the triangles is greater than the length of the other side)
For example:
Sum of three sides: 6
1 3 2\n
2 2 2\n
2 3 1\n
3 1 2\n
3 2 1\n
number of triangle: 5
my code:
#include <stdio.h>
int main() {
int a = 0, b = 0, c = 0, count=0;
int sum = a + b + c;
printf("Sum of three sides: ");
scanf_s("%d", &sum);
for (a = 1; a < sum; a++)
for (b = 1; b < sum; b++)
for (c = 1; c < sum; c++)
if (a + b > c && a+b+c==sum)
printf("%d\t %d\t %d\n", a, b, c);
printf("number of triangle: %d", count );
}
I don't know how to output the number of triangles and how to put
"the sum of the lengths of the two sides of the triangles is greater than the length of the other side" into code.
4 1 1 is not a valid triangle. a + b > c is the triangle formula.
As it has been pointed out in comments/answers the main problem is that your code only checks for a + b > c where it should for all combination of "sum of two sides being larger than the last side".
Besides that there is no reason for using 3 loops. When a and b is selected by the outer two loops, c can be calculated like c = sum - a - b. Something like:
#include <stdio.h>
int main() {
int a, b, c, count=0;
int sum;
printf("Sum of three sides: ");
scanf_s("%d", &sum);
for (a = 1; a < sum; a++)
{
for (b = 1; b < sum; b++)
{
c = sum - a - b;
if (c < 1) break; // No reason to continue so break out of inner loop
if ((a + b > c) && (a + c > b) && (b + c > a))
{
printf("%d\t %d\t %d\n", a, b, c);
++count;
}
}
}
printf("number of triangle: %d", count );
return 0;
}
You can improve the program performance further by considering the condition for the loops:
for (a = 1; a < sum; a++)
Is it really necessary to continue all the way to sum - 1 ?
Can there ever be a triangle where a is greater or equal to sum/2 ?
Your code does not increment the count variable at any place. It just lies there unchanged throughout. Also, you are checking for the validity of just one side and not for the satisfaction of conditions for all sides.
And also, your sample output is wrong, [1 3 2], [2 3 1], [3 1 2], [3 2 1], etc are not valid triangles. Only [2,2,2] satisfies the triangle condition. Please cross check the expected output before posting it as a requirement here.
here is a possible working code:
#include<stdio.h>
int main() {
int a = 1, b = 1, c = 1, count=0;
int sum = 0;
printf("Sum of three sides: ");
scanf("%d", &sum);
while(a < sum) {
b=1;
while(b < sum) {
c=1;
while(c < sum) {
if ((a+b+c == sum)&&(a+b>c)&&(a+c>b)&&(c+b>a))
{
count+=1;
printf("Triangle %d:\nSide 1: %d Side 2: %d Side 3: %d\n\n", count, a, b, c);
}
c++;
}
b++;
}
a++;
}
printf("Possible number of triangles: %d", count );
return(0);
}
You have to check the condition for all three sides and you have to increment count for a successful test.
#include<stdio.h>
#include<stdlib.h>
int main() {
int a = 0, b = 0, c = 0, count=0;
int sum = a + b + c;
printf("Sum of three sides: ");
scanf("%d", &sum);
for (a = 1; a < sum; a++)
for (b = 1; b < sum; b++)
for (c = 1; c < sum; c++)
if ((a+b+c==sum) && ((a + b > c) && (a + c > b) && (c + b > a)))
{
printf("%d\t %d\t %d\n", a, b, c);
count++;
}
printf("number of triangles: %d", count );
}
Output:
Sum of three sides: 6
2 2 2
number of triangle(s): 1
Sum of three sides: 7
1 3 3
2 2 3
2 3 2
3 1 3
3 2 2
3 3 1
number of triangle(s): 6
The condition ((a+b+c==sum) && ((a + b > c) && (a + c > b) && (c + b > a))) may be improoved by adding && a<=b && b<=c to avoid the generation of dublicate triangles. for example, 3 3 1 is the same as 3 1 3 and 1 3 3.
(P.s I put this as an answer because I do not have enough reputation to post a comment. )

General Fibonacci, why is it overflowing?

I am trying to create a general fibonacci series where the starting values can be variable, depending on what the user wants. For example, instead of starting with values 0, 1, or 1, 1, as it usually does, it can start with 3, 6, or 10, 21, or whatever the user wants. We then want to get the nth value of that series.
I tried my code for a = 10 and b = 21, and I wanted a big value, however it didn't work. So I started checking where the problem was. With those starting values: for n = 37, 38, 39, the output should be 405812042, 656617677, 1062429719 respectively. When I run my code for values n = 37 and n = 38, both answers are correct. However when I try 39, this is the value I get: 62429712.
This is my code:
#include <stdio.h>
int main(void)
{
unsigned long long a, b, hn, value;
int scenarios;
scanf("%d", &scenarios);
for (int i = 0; i < scenarios; i++){
scanf("%lld%lld%lld", &a, &b, &hn);
if (hn == 1)
value = a;
else if (hn == 2)
value = b;
else{
for (int j = 3; j <= hn; j++){
value = a + b;
a = b;
b = value;
}
//value %= 1000000007;
}
printf("%lld\n", value);
}
}
EDIT: According to the problem specification, the answer should be module 1000000007. The output I get if I get the 514th value is 2903631044495864380, and to be honest I don't know how to verify this value. If I do 2903631044495864380 mod 1000000007, my answer is 170447212, but according to the problem this answer should be 859861000. Any idea how to verify this?
Change this:
scanf("%lld%lld%lld", &a, &b, &hn);
to this:
scanf("%llu%llu%llu", &a, &b, &hn);
Change this:
printf("%lld\n", value);
to this:
printf("%llu\n", value);
since these variables are of type unsigned long long.
EDIT
It seems like (from your edit) you need to change this:
value = a + b;
to this:
value = (a + b) % 1000000007;
You misinterpreted the point where you should calculate the modulo according to your exercise.
You don't compute the end sum before doing modulo, but you apply modulo to the intermediate results:
for (int j = 3; j <= hn; j++)
{
value = (a + b) % 1000000007; // there
a = b;
b = value;
}
Also, change your scan/print format to '%llu', as #gsamaras suggested.

Any reason why a loop wouldn't terminate even with an 'i' limiting value of repeats?

I'm doing this assignment for college in C, should be fairly simple, but a loop in it doesn't seem to terminate so the code won't work properly; even if I put in an i value to limit the amount of times it loops. Tried it with a for loop too, still gets stuck.
The code is supposed to take in values of coefficients and try to work out a root for a cubic equation by finding the midpoint between two large values and trying that out to see if it gets 0, if it doesn't, it should change one of the limits to the midpoint value. Here's the relevant code:
int main (void)
{
int i, u=1000, l=-1000;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (abs(u - l) > 0.001 && i < 10)
{
mid= (u + l)/2;
y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d;
if(y == 0) break;
else if(y < 0) l = mid;
else u = mid;
i++;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
Any help would be appreciated, thanks!
edit: Oh my god I'm an idiot. Always the small things. The code still isn't working but at least it's not stuck anymore, thanks guys!
You declared i, but did not initialize it, so it is set to whatever random value was left in memory.
For this example, lets say that value was -12,345.
Then i can be incremented over 12,000 times before it is greater than 10!
Your loop will run when i is incremented 12,355 times, and its value becomes 10, and the test i < 10 finally fails.
To fix this, initialize i = 0:
int i=0;
2 things. Initialize i to 0. this will ensure it terminates after 10 loops.
More important for your problem though, you have declared u and l as integers, I think you need to declare them as floats.
You need to initialize i: int i = 0;
This should work for you! You need to initialize i.
#include <stdio.h>
#include <math.h>
int main (void)
{
int i = 0, u = 1000, l =- 1000;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (abs(u-l)>0.001 && i<10)
{
mid = (u + l)/2;
y = a*pow(mid,3) + b* pow(mid,2) + c*mid + d;
if(y == 0)
break;
else if(y<0)
l = mid;
else
u = mid;
i++;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
If you make u and l be floats then your while-loop terminates without i. Before that, abs(u-l) where u-l are ints will only terminate if a root is at zero. You also need to use fabs() instead of abs():
int main (void)
{
float u=1000.0, l=-1000.0;
float a, b, c, d, mid, y;
scanf(" %f %f %f %f", &a, &b, &c, &d);
while (fabs(u - l) > 0.001)
{
mid= (u + l)/2.0;
y = a * pow(mid, 3) + b* pow(mid, 2) + c * mid + d;
if(y == 0) break;
else if(y < 0) l = mid;
else u = mid;
}
printf("\nThere is a root at: x = %.3f\n", mid);
}
Seems like you still have something wrong in the bisection algorithm condition when you reset l and u to mid. I'm attaching a fixed version, and I used different variable names (sorry) to keep my head clear:
#define NMAX 1000
#define TOL 0.00001
int sign( float x ) {
if (x > 0.0) return 1;
if (x < 0.0) return -1;
return 0;
}
int main (void)
{
int n=0;
float fa, fc, b=1000.0, a=-1000.0;
float p3,p2,p1,p0,c;
scanf(" %f %f %f %f", &p3, &p2, &p1, &p0);
while(n<NMAX)
{
c = (a + b)/2.0;
fc = p3*pow(c, 3) + p2*pow(c, 2) + p1*c + p0;
if(fc == 0.0 || (b-a)/2.0 < TOL ) break;
fa = p3*pow(a, 3) + p2*pow(a, 2) + p1*a + p0;
if( sign(fc) == sign(fa) )
a = c;
else
b = c;
n++;
}
if(n==NMAX) {
printf("Method failed.\n");
}
else {
printf("\nThere is a root at: x = %.3f\n", c);
}
}

Resources