Sort Red, Green Blue using C - c

this is my first time using Stack Overflow, and I must warn you that I only started to learn C earlier this week. I am trying to write a simple program that will find which color has the greatest value out of the RGB spectrum. It has a manual input for each color, but when It is finished, I am getting 2 odd numbers ranging in the millions. Could somebody help a noob? Here is the code that I've written so far:
#include <stdio.h>
int main()
{
int mm, m;
int hh, h;
int r, g, b, c;
printf("Enter Value For Red (0-255)\n");
scanf("%d", &r);
printf("Enter Value For Green (0-255)\n");
scanf("%d", &g);
printf("Enter Value For Blue (0-255)\n");
scanf("%d", &b);
if ( r > g );
if ( r > b );
mm = r;
if ( g > b );
m = b;
if ( b > g );
m = g;
if ( r < b );
mm = b;
m = g;
if ( g > r );
if ( g > b );
mm = g;
if ( r > b );
m = b;
if ( b > r );
m = r;
if ( g < b );
mm = b;
m = r;
printf("%d\n", &mm);
printf("%d\n", &m);
}

printf("%d\n", &mm);
printf("%d\n", &m);
Should be:
printf("%d\n", mm);
printf("%d\n", m);
The & gets the address of the variable. When you're setting a variable via scanf() you need to give the address so that it can be set. When you're printting the value of a variable via printf() you need to just provide the name, not the address.
What you're seeing right now is the address of where your variables are stored on the stack as a decimal number.
Side note, your code doesn't work the way you think it does:
if ( r > g );
if ( r > b );
mm = r;
if ( g > b );
m = b;
if ( b > g );
m = g;
if ( r < b );
mm = b;
m = g;
It takes more then indentation to get this working, right now it's doing the following:
mm = r;
m = b;
m = g;
mm = b;
...
everytime you run it, because the if's are being chucked. You can't have ; after an if statement or it doesn't do what's below it. Also use curly brackets { } to make a scope to do more then one thing:
if ( r > g )
{
if ( r > b )
{
mm = r;
if ( g > b )
m = b;
if ( b > g )
m = g;
}
if ( r < b )
{
mm = b;
m = g;
...
Is what you wanted.

There is a reason scanf() accepts pointers to its arguments: it has to modify them.
However, printf() does not modify its arguments (generally... - there are exceptions), so you don't have to pass it pointers. Change
printf("%d\n", &mm);
printf("%d\n", &m);
to
printf("%d\n", mm);
printf("%d\n", m);

You should make use of { and } after your ifs. Your form of if ( r > g ); does hardly work. Especially the semi-colons are wrong here.

Related

Given the expression n = p × k + r , (0 ≤ r < k). Find the values ​of p and r when known n and k

I've been trying to do this but I'm getting an error Time Limit Exceeded, please help!
Example of input and exepected output
Input#1: 5 2
Output#1: 2 1
#include<stdio.h>
int main(){
long long n, k, p, r;
scanf("%lld %lld", &n, &k);
if (r >= 0 && r < k){
if (n >= 1){
p = (n - r) / k;
r = n / (p * k);
}
}
printf("%lld %lld", p, r);
return 0;
}
Here you can take the reference from the code written in python, I first calculate the highest multiple of k (less than k) divisible by n. It is calculated by the // operator in python. Like, 37/5=7.4 but 37//4 gives 7 (floor of 7.4). Then I calculate r and finally prints them
# 37 = p*5 + r
# take n=37 and k=5
n,k = map(int,input().split()) # take n,k as input
p = n//k # it will max multiple of k divisible by n
r = n - (p*k) # r = 37 - (7*5)
print("p =",p," and r=",r) # print answer here
The variable r is not initialized and has an indeterminate value
long long n, k, p, r;
So this if statement
if (r >= 0 && r < k){
at once invokes undefined behavior.
What you need is to include the header
#include <stdlib.h>
and to use the function lldiv declared in this header that calculates the quotient and the remainder of two numbers.
Here is a demonstration program.
#include <stdlib.h>
#include <stdio.h>
int main( void )
{
long long int n = 100, k = 13;
lldiv_t result = lldiv( n, k );
long long int p = result.quot;
long long int r = result.rem;
printf( "p = %lld, r = %lld\n", p, r );
}
The program output is
p = 7, r = 9
Or instead of the function you could use the two operators / and % like
p = n / k;
r = n % k;

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!! :)

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

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);
}
}
}
}
}

Relatively prime check?

Ok so relatively prime means that two numbers have no common factors greater than 1. It can also be viewed as two numbers that have gcd = 1.
So along those lines, this is the code i wrote to find two relatively prime numbers e,z :
for(e = 0,flag=0; (flag==1); e++){
if( gcd( e, z ) == 1){ // z in this example is 60
flag = 1;
}
}
printf("e = %d\n",e);
and the gcd function is defined as :
int gcd(int i, int x){
if(x % i == 0) return( i );
return( gcd( x % i, x ) );
}
when I set z = 60, the e I get is e= 0 ... Actually I keep getting the same e with which I initialize the for loop
What am I doing wrong? Is there any other way of finding if two numbers are relatively prime?
EDIT:
Ok as per the suggestion from minitech here is the modified code:
for(e = 2,flag=0; !flag; e++){
if( gcd( e, z ) == 1){
flag = 1;
}
}
now when I set my z=60 , my e is coming out to be e = 60 which is again wrong. Correct answer should be e = 7
You shouldn’t start at zero
Your flag condition should be !flag
After fixing that, you will always get 1, because it’s relatively prime to everything. Try starting at z - 1 and decrementing if you want the biggest one. You should also just break; instead of keeping a flag.
This is a little fragile, since it can't handle a zero argument; e.g.,
gcd(z, z) = gcd(z, 0) = gcd(0, z) = |z|.
I'd go with something like:
unsigned gcd (unsigned u, unsigned v)
{
unsigned t;
for (; (t = v) != 0; u = t)
v = u % v;
return u;
}
I use unsigned types, because there's no reason to use negative arguments - they don't affect the result of a gcd, which is always non-negative.

Bug in the routine converting RGB to TSL and back

I am trying the TSL color space (Tint Saturation Luminance). Reading this wiki page
TSL color space
I have tried to code two simple rgb2tsl and tsl2rgb routines:
/// input: r,g,b in [0..1]
/// output: t,s,l in [0..1]
void RGB2TSL( float r, float g, float b, float &t, float &s, float &l )
{
float rn, gn;
if ( r+g+b == 0.0f )
{
t = s = l = 0.0f;
return ;
}
rn = r/(r+g+b);
gn = g/(r+g+b);
float r1, g1;
r1 = rn-1.0f/3.0f;
g1 = gn-1.0f/3.0f;
l = 0.299*r+0.587*g+0.114*b;
if ( g1 > 0 )
t = (1.0f/(2.0f*PI))*atan2f(r1, g1) + 1.0f/4.0f;
else if ( g1 < 0 )
t = (1.0f/(2.0f*PI))*atan2f(r1, g1) + 3.0f/4.0f;
else
t = 0;
s = sqrtf(9.0f/5.0f*(r1*r1+g1*g1));
}
/// input: t,s,l in [0..1]
/// output: r,g,b in [0..1]
void TSL2RGB( float t, float s, float l, float &r, float &g, float &b )
{
float r1, g1, k, x;
x = -sinf(2*PI*t);
if ( x != 0 )
x = cosf(2*PI*t)/x;
if ( t > 0.5f )
g1 = -s*sqrtf(5.0f/(9.0*(x*x+1.0f)));
else if ( t < 0.5f )
g1 = s*sqrtf(5.0f/(9.0*(x*x+1.0f)));
else
g1 = 0;
if ( t == 0 )
r1 = (sqrtf(5.0f)/3.0f)*s;
else
r1 = x*g1+1.0f/3.0f;
k = 1.0f/(0.185*r1+0.473*g1+0.114);
r = k*r1;
g = k*g1;
b = k*(1-r1-g1);
}
Please don't consider the code quality, just focus on the fact that there is an error I am unable to find: when I convert a rgb triple to tsl triple and, without changing anything, I convert it back to r, g, b, I don't get the original image, but really different and wrong in any possible way!
RGB2TSL looks good to me, however there are clipping issues I believe. I think some values need to be clamped, but I'm not sure myself exactly which ones.

Resources