I wanted to check if a fraction 2 4 (for example) can be simplified to 1 2!!
However logical condition fails.
#include <stdio.h>
int main()
{
int a,b,live=1;
printf("\n\nInput integers for fraction:");
scanf(" %d%d",&a,&b);
while(live){
if(!(a%2 && b%2)){
a/=2;
b/=2;
}else if(!(a%3 && b%3)){
a/=3;
b/=3;
}else if(!(a%5 && b%5)){
a/=5;
b/=5;
}else if(!(a%7 && b%7)){
a/=7;
b/=7;
}else live--;
}
printf("Simplified Fraction is %d/%d",a,b);
}
The condition a%2 is equivalent to a%2 != 0, i.e. it tests if a is not divisible by 2. From De Morgan's Laws, the condition if(!(a%2 && b%2)) is equivalent to if(!(a%2) || !(b%2)) or if((a%2 == 0) || (b%2 == 0)), which is not what you want.
You really want to test if((a%2 == 0) && (b%2 == 0)) -- that is, if both are divisible by 2, not if either is divisible by 2. Writing it this way is also much less confusing.
And it should also be obvious that in order to simplify any fraction, you need to test for all possible prime factors, which is impossible to do with a finite number of if statements. The recommended way of doing this is to use the Euclidean algorithm to determined the greatest common divisor of the numerator and denominator, and then you divide both by the GCD to get the fraction in reduced form.
(!(a%2 && b%2)) will yield true even if only one of a%2 or b%2 holds.
Have a look at the following example:
3/4 -> a%2 == 0, b%2 == 1 -> (a%2 && b%2) == 0 -> (!(a%2 && b%2)) == 1
You are looking for (a%2 == 0 && b%2 == 0) instead of your condition, and similarly for other conditions.
An "after an accepted answer" answer.
This does not detail the issues with OP's code nicely like #Adam Rosenfield, but does address the larger OP desire of "I wanted to check if a fraction 2 4 (for example) can be simplified to 1 2!!" in a general way.
Use the Euclidean Algorithm to find the greatest-common-denominator, then divide a,b by it. No need to generate prime number list. Very fast.
// Euclidean Algorithm
unsigned gcd(unsigned a, unsigned b) {
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}
#include <stdio.h>
int main() {
int a, b;
for (;;) {
printf("\nInput positive fraction like 12/30: ");
if (scanf("%u/%u", &a, &b) != 2)
break;
unsigned g = gcd(a, b);
a /= g;
b /= g;
printf("Simplified Fraction is %u/%u", a, b);
}
return 0;
}
In addition to the logical or issue identified by others, you also have an infinite loop with your while condition. You don't need (or want) to loop with your current code. Try this
#include <stdio.h>
int main ()
{
int a, b;
printf ("\n\nInput integers for fraction:");
scanf (" %d%d", &a, &b);
while (a % 2 == 0 && b % 2 == 0)
{
a /= 2;
b /= 2;
}
while (a % 3 == 0 && b % 3 == 0)
{
a /= 3;
b /= 3;
}
while (a % 5 == 0 && b % 5 == 0)
{
a /= 5;
b /= 5;
}
while (a % 7 == 0 && b % 7 == 0)
{
a /= 7;
b /= 7;
}
printf ("Simplified Fraction is %d/%d", a, b);
}
Output(s) with your given input(s)
Input integers for fraction:2 4
Simplified Fraction is 1/2
Input integers for fraction:8 24
Simplified Fraction is 1/3
Related
I'm making a function that checks if 2 integers are relatively prime / coprime. The function returns 1 if they are relatively prime and 0 if they are not relatively prime.
The function should be able to accept any integer in any order, given that a and b are both not 0;
To my knowledge having a gcd of -1 is the same as having a gcd of 1. Is that correct?
This is my code:
int relatively_prime(int a, int b){
if (a == 0 || b == 0) return 0;
if (a%b == 0 && (b != 1 || b != -1)) return 0;
else if (a%b== 0 && (b == 1 || b == -1)) return 1;
else return relatively_prime(b, a % b);
}
Is this correct? Is there any way to simplify or improve my code?
Thanks!
int gcd(int a, int b)
{
a=abs(a);
b=abs(b);
if (b == 0)
return a;
return gcd(b, a % b);
}
Now if the result is 1 they are coprime . You can convert negative number into positive to see if they are co prime and simplify the code .Technically speaking we can write 0 as 0* any number so 0 will not be co prime with any number other than 1 .
Is this correct?
No.
b != 1 || b != -1 is always true. So code is like
int relatively_prime(int a, int b){
if (a == 0 || b == 0) return 0;
if (a%b == 0 /* && (b != 1 || b != -1) */) return 0;
// a%b== 0 is never true below after the above line
// else if (a%b== 0 && (b == 1 || b == -1)) return 1;
else return relatively_prime(b, a % b);
}
... and does not return 1.
OP's code fails with undefined behavior (UB) at least with the case of relatively_prime(INT_MIN, -1) as it attempts INT_MIN % -1.
Is there any way to simplify ?
// Do not call with gcd_recursive(INT_MIN, -1)
static int gcd_recursive(int a, int b) {
if (b == 0) return a;
return gcd_recursive(b, a % b);
}
int relatively_prime_alt(int a, int b) {
if (b == -1) b = 1; // Avoid a INT_MIN % -1 in gcd_recursive()
int gcd = gcd_recursive(a, b);
return gcd == 1 || gcd == -1;
}
I'd like to ask the following misunderstandings of C language, which I see I'm having.
I'm sorry if the code is not properly indented, I tried as much as I could but there are not so many guides on the internet.
The program asked given a starting number 'val' and a Even-Odd or Odd-Even alternating sequence (which stops whenever this rules is violated) to print the greater prime number with 'val'.
I tried with two functions and the main: one to control the GCD between two given numbers and the other to keep tracks of the greatest one, but I think I miss something in the code or in the conception of C function,
Because when compiled it returns me 0 or great number which I'm not entering.
One example to understand what I should do:
If my sequence was 10, 7, 8, 23 and my val was 3, I had to print 23, because it is the greatest integer prime with 3.
Here's the code :
#include <stdio.h>
int mcd(int a, int b)
{ // Gcd function
if (a == 0)
return b;
else
return mcd(b % a, b);
}
int valuta(int val, int h) // Valuing Max function
{
int temp = 0;
if (mcd(val, h) == 1 && h > temp)
temp = h;
return temp;
}
int main()
{
int val, d, x, y, z, t, contatore = 1;
scanf("%d", &val);
scanf("%d%d", &x, &y);
if (x > y && mcd(val, x) == 1)
{ // Two options
t = x;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
}
if ((x % 2 == 0 && y % 2 == 0) || (x % 2 == 1 && y % 2 == 1))
{ // Bad case
if (x > y && mcd(val, x) == 1)
{
t = x;
contatore = 0;
}
else if (y > x && mcd(val, y) == 1)
{
t = y;
contatore = 0;
}
}
else
{
while (contatore == 1)
{
scanf("%d", &z);
t = valuta(val, z);
if (x % 2 == 0 && z % 2 == 0)
{ // Even- Odd - Even
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 0)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
if (x % 2 == 1 && z % 2 == 1)
{ //Odd- Even- Odd
scanf("%d", &d);
t = valuta(val, d);
if (d % 2 == 1)
{
contatore = 0;
}
else
{
contatore = 0;
}
}
}
}
printf("%d\n", t);
return 0;
}
PS. Is there any way to reduce the number of lines of code or to reduce the effort in coding? I mean, a straightforward solution will be helpful.
Your valuta() function is flawed in that it needs to return the maximum qualifying value so far but has no knowledge of the previous maximum - temp is always zero. The following takes the previous maximum as an argument:
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) == 1 && h > previous ) ? h : previous ;
}
And is called from main() thus:
t = valuta( val, x, t ) ;
The test mcd(val, h) == 1 is flawed, because mcd() only ever returns the value of parameter b which is not modified in the recursion, so will never return 1, unless the argument b is 1. Since I have no real idea what mcd() is intended to do, I cannot tell you how to fix it. It appear to be a broken implementation of Euclid's greatest common divisor algorithm, which correctly implemented would be:
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
But I cannot see how that relates to:
"[...] he greatest integer prime with 3 [...]
The odd/even even/odd sequence handling can be drastically simplified to the extent that it is shorter and simpler than your method (as requested) - and so that it works!
The following is a clearer starting point, but may not be a solution since it is unclear what it is it is supposed to do.
#include <stdio.h>
#include <stdbool.h>
int mcd(int a, int b)
{
if(b == 0)
return a;
else
return mcd(b, a % b);
}
int valuta(int val, int h, int previous )
{
return ( mcd(val, h) && h > previous ) ? h : previous ;
}
int main()
{
int val, x, t ;
printf( "Enter value:") ;
scanf("%d", &val);
typedef enum
{
EVEN = 0,
ODD = 1,
UNDEFINED
} eOddEven ;
eOddEven expect = UNDEFINED ;
bool sequence_valid = true ;
printf( "Enter sequence in odd/even or even/odd order (break sequence to exit):\n") ;
while( sequence_valid )
{
scanf("%d", &x);
if( expect == UNDEFINED )
{
// Sequence order determined by first value
expect = (x & 1) == 0 ? EVEN : ODD ;
}
else
{
// Switch expected odd/even
expect = (expect == ODD) ? EVEN : ODD ;
// Is new value in the expected sequence?
sequence_valid = (expect == ((x & 1) == 0 ? EVEN : ODD)) ;
}
// If the sequence is valid...
if( sequence_valid )
{
// Test if input is largest qualifying value
t = valuta( val, x, t ) ;
}
}
// Result
printf("Result: %d\n", t);
return 0;
}
I have written this code for C to print prime numbers from 1-300
GNU GCC Compiler shows the following error:
error: invalid operands to binary % (have ‘double’ and ‘int’)
if (sqrt(num) == 0 || sqrt(num) % 2 != 0)
My code is this:
#include <stdio.h>
#include <math.h>
int main() {
/*Created by Suvid Singhal Date:- January 2, 2017*/
int num;
printf("Welcome to 1-300 prime numbers C Program!!!");
for (num = 0; num <= 300; num++) {
if (sqrt(num) == 0 || sqrt(num) % 2 != 0) {
printf("%d\n", num);
} else {
continue;
}
}
return 0;
}
You have lots of thing going wrong in your answer.
Let's check them one by one.
Your idea about prime number is not clear. A prime number has no divisior except the number and 1. (1 is not a prime number).
How to check if a number is prime or not?
You can check all the `numbers <=square root of (x). So you need to check if someone (except 1 ) divides the number. If yes then it is not prime else it is.
Implementation Details
int check= 0;
for(int i=2;i<=(int) sqrt(x);i+=1)
if(n%i == 0)
{
check = 1;
n is non-prime;
break; // no need to check
}
if(check == 0)
n is prime
sqrt() return double and ...
Modulous can be applied over an int so you have to cast it to that.
If you want to avoid it all
for(int i=2;i*i<=x;i++)
...
For you to study
Learn about sieve method to get the primes. For 300 numbers probably it doesn't matter what you use but in case it is 10000000 then you will definitely want to give it a read.
% operator is for integers. You may want to use fmod() or an integer cast.
if ( sqrt( num ) == 0 || fmod( sqrt( num ), 2 ) != 0 )
or
if ( sqrt( num ) == 0 || (int) sqrt( num ) % 2 != 0 )
This should fix your compilation errors.
ps: If you are looking for an awesome way to generate prime numbers, see Sieve of Erastosthenes
In the code sample you have given, it is not quite clear how you intend to determine whether a number is prime or not. You have the following condition if (sqrt(num) == 0 || sqrt(num) % 2 != 0) to apparently determine a number as prime. But this condition is syntactically invalid. As others have pointed out, you can't do modulo operation on a non-int number as returned by the sqrt function. What value, do you think, is returned by the operation sqrt(num) % 2 and what has it do with a number being prime? Your usage of continue has also no importance. Maybe you are a little confused between break and continue. I am giving you a sample program. Try to learn what your mistakes are from this:
int isPrime = 1;
for(int i=2;i<=300;i++) {
isPrime = 1;
for(int j=2; j!=i && j <= ceil(sqrt(i));j++) {
if(i%j == 0) {
//Not a prime number
isPrime = 0;
break;
}
}
if(isPrime) {
printf("%d\n", i);
}
}
Changing
if( sqrt(num) == 0 || sqrt(num) % 2!=0 )
to
if( sqrt(num) == 0 || (int)sqrt(num) % 2!=0 )
Should fix compilation errors. See error: invalid operands to binary % when taking modulus of float for more info.
i have a code that prints out the number of peaks and their given magnitudes. the input is in the form of a single line that contains random integers separated by white space. a peak is only defined to be so when it is directly preceded and followed by a smaller value.
examples:
0 4 18 18 26 40 40 29 25 2 0 //has one peak of magnitude 40.
20 10 20 /*has no peaks, because both 20's are either not
preceded or followed by a smaller number.*/
the code fails to behave correctly when the input data, c, begins with a declining set of numbers.
for example, the input: 9 8 7 6 5 4 returns a peak of "9", when it shouldn't return any magnitude.
another situation where it's behaving incorrectly is when we have the following input: 10 10 10 5 5 5 12 12 12 -1. its returning a magnitude of "10", while again, it shouldn't return any magnitude because it doesn't fulfill the conditions of a peak .
the following is the code:
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 0;
int c = 0;
int counter = 0;
scanf("%d", &c);
printf("Number Magnitude\n");
while (c >= 0){
if ((b > a) && (b > c)) { //to check if we have a peak
counter++;
printf("%4d%11d\n", counter, b);
a = b;
b = c;
scanf("%d", &c);
}
else if ((a < b) && (b == c)) {
b = c;
scanf("%d", &c);
}
else {
a = b;
b = c;
scanf("%d", &c);
}
}
}
i prefer to keep the level of coding as minimum as possible, as i haven't done more than loops and if statements at this stage.
The issue is being caused because you initialize your boundary values to the minimum possible value. Any possible peak value will test positive when compared to that boundary value.
A small change fixes it, both boundary values should be set to a value that tests negative when compared to any possible peak value:
int a = INT_MAX;
int b = INT_MAX;
You will however to detect new lines and reset your values if you want to be able to do multiple lines of input, but I believe this is an existing problem
In that case, you should try to ask the program to mimic what you would to by hand: you must considere 3 value, so you must read 3 values before testing for a peak. And you should always control the return value from scanf to be able to process and end of file or an incorrect input.
Your code could become:
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 0;
int c = 0;
int counter = 0;
int cr;
cr = scanf("%d%d%d", &a,&b,&c);
if (cr != 3) {
printf("Incorrect input\n");
return 1;
}
printf("Number Magnitude\n");
while ((cr > 0) && (c >= 0)) {
if ((b > a) && (b > c)) { //to check if we have a peak
counter++;
printf("%4d%11d\n", counter, b);
a = b;
b = c;
}
else if ((a >= b) || (b != c)) {
a = b;
b = c;
} // nothing to do if a<b and b==c
cr = scanf("%d", &c); // read once outside of the loop
}
return 0;
}
BTW, above code allows multi-line input.
What is the efficient way in C program to check if integer is one in which each digit is either a zero or a one ?
example 100 // is correct as it contains only 0 or 1
701 // is wrong
I tried for
int containsZero(int num) {
if(num == 0)
return 0;
if(num < 0)
num = -num;
while(num > 0) {
if(num % 10 == 0)
return 0;
num /= 10;
}
return -1;
}
int containsOne(int num) {
if(num == 0)
return 0;
if(num < 0)
num = -num;
while(num > 0) {
if(num % 10 == 1)
return 0;
num /= 10;
}
return -1;
}
You can peel of every digit and check it. This takes O(n) operations.
int input;
while (input != 0)
{
int digit = input %10; //get last digit using modulo
input = input / 10; //removes last digit using div
if (digit != 0 && digit != 1)
{
return FALSE;
}
}
return TRUE;
Well, in the worst case you have to check every digit, so you cannot have an algorithm better than O(d), where d is the number of digits.
The straight-forward approach satisfies this:
int n = 701;
while ( n != 0 && (n % 10) <= 1 )
{
n /= 10;
}
if ( (n % 10) > 1 )
{
printf("Bad number\n");
}
else
{
printf("Good number\n");
}
This assumes positive numbers though. To put it into a general function:
int tester(int n)
{
if ( n < 0 )
{
n = -n;
}
while ( n != 0 && (n % 10) <= 1 )
{
n /= 10;
}
return ( (n % 10) <= 1 );
}
Demo: http://ideone.com/jWyLdl
What are we doing here? We check if the last decimal digit (n % 10) is either 0 or 1, then cut of the last digit by dividing by ten until the number is 0.
Now of course there is also another approach.
If you are guaranteed to have e.g. always 32bit integers, a look-up table isn't that large. I think it may be around 2048 entries, so really not that big.
You basically list all valid numbers:
0
1
10
11
100
101
110
111
...
Now you simply search through the list (a binary search is possible, if the list is sorted!). The complexity with linear search would be, of course, worse than the approach above. I suspect binary search beeing still worse in actual performance, as you need to jump a lot in memory rather than just operating on one number.
Anything fancy for such a small problem is most probably overkill.
The best solution I can think of, without using strings:
while(n)
{
x = n%10;
if(x>1)
return -1;
n /= 10;
}
return 0;
Preamble
Good straightforward algorithms shown in other answer are O(n), being n the number for the digits. Since n is small (even using 64bit integer we won't have more than 20 digits), implementing a "better" algorithm should be pondered, and meaning of "efficient" argued; given O(n) algorithms can be considered efficient.
"Solution"
We can think about sparse array since among 4 billions of numbers, only 2^9 (two symbols, 9 "positions") have the wanted property. I felt that some kind of pattern should emerge from bits, and so there could be a solution exploiting this. So, I've dumped all decimal numbers containing only 0 and 1 in hex, noticed a pattern and implemented the simplest code exploiting it — further improvements are surely possible, e.g. the "table" can be halved considering that if x is even and has the property, then x+1 has the property too.
The check is only
bool only01(uint32_t n)
{
uint32_t i = n & 0xff;
uint32_t r = n >> 8;
return map01[i][0] == r || map01[i][1] == r;
}
The full table (map01) and the test code are available at this gist.
Timing
A run of the test ("search" for numbers having the property between 0 and 2 billions — no reason to go beyond) with my solution, using time and redirecting output to /dev/null:
real 0m4.031s
user 0m3.948s
A run of the same test with another solution, picked from another answer:
real 0m15.530s
user 0m15.221s
You work with base 10, so, each time check the % 10:
int justOnesAndZeros(int num) {
while ( num )
{
if ( ( num % 10 != 1 ) && ( num % 10 != 0 ) )
{
return FALSE;
}
num /= 10;
}
return TRUE;
}