how to fix this unexpected output? - c

I have been doing on decomposing Integers to prime numbers, but i got stucked , it s working for one prime number, but when the iteration continues then it s not working properly and I can t come up with any solution.
For example for number 12 i expect output 2^2 x 3
but instead program stops at 2^2 x and new input is expected.
int main(int argc, char *argv[])
{
int number;
int stop = 1;
int prime = 0;
int sqr = 0;
while (stop == 1) {
/**------ERROR------ **/
if(scanf("%d",&number) != 1 || number < 0 ){
fprintf(stderr,"%s","Error: Chybny vstup!\n");
return 100;}
if(number == 0){
stop = 0;
break;}
/**------DECOMPOSITION------ **/
for (int index = 1;index <=number;){
if(number == 1){
//Ak sa input cislo rovna 1 tak vypise nasledovne riadky
printf("Prvociselny rozklad cisla 1 je:\n");
printf("1\n");
break;}
if(number % (index + 1) == 0){
// ak je cislo % index +1 (pociatocna hodnota je 2) tak sa vydeli cislom index + 1
// do prime sa ulozi dane prvocislo
// ak je delitelne prvocislom pripocitame sqr +1
// cyklus pokracuje s rovnakym indexom
number = number / (index + 1);
prime = index + 1;
sqr = sqr + 1;
continue;}
else{
if(sqr == 1){
// vypise len prvocislo
printf("%d",prime);}
if(sqr != 1){
//vypise prvocislo aj mocninu
printf("%d^%d", prime,sqr);}
if(number != 1){
printf(" x ");}
else{
printf("\n");
break;}
}
index = index + 1;
sqr = 0;
}
}
return 0;
}

I see two problems in the code:
The special case for number == 1 is being handled inside the loop. That special case is much easier to handle before the loop.
Counting the exponent is mixed into the loop that updates the factor. It's much easier to use a second loop to count the exponent.
#include <stdio.h>
int main(void)
{
while (1){
/**------GET USER INPUT------ **/
int number;
if(scanf("%d",&number) != 1 || number < 0 ){
fprintf(stderr,"%s","Error: Chybny vstup!\n");
return 100;
}
/**------HANDLE SPECIAL CASES------ **/
if(number == 0){
break;
}
if(number == 1){
printf("Prvociselny rozklad cisla 1 je:1\n");
continue;
}
/**------DECOMPOSITION------ **/
for (int factor = 2; factor <= number; factor++){
int exponent = 0;
while(number % factor == 0){
number /= factor;
exponent++;
}
if (exponent == 1){
printf("%d", factor);}
else if (exponent > 1){
printf("%d^%d", factor, exponent);}
if(exponent != 0 && number != 1){
printf(" x ");}
}
printf("\n");
}
}

Related

How to express integer as a product of its prime factors?

//Determine the prime factors of a number
for(i = 2; i <= num; i++) { //Loop to check the factors.
while(num % i == 0) { //While the input is divisible to "i" which is initially 2.
printf("%d ", i); //Print the factor.
num = num / i; //Divide the num by "i" which is initially 2 to change the value of num.
}
}
I know that this is the way of finding the prime factors of a number using for loop. But I don't know how to express the output integer as a product of its prime factors.
For example, INPUT IS: 10 ||
OUTPUT IS: 2 x 5 = 10. How do we do this? TIA.
You should:
Save the original value.
Print the operator x between each prime factors.
Print the original value at the end.
#include <stdio.h>
int main(void) {
int num;
int i;
int start_num;
int is_first = 1;
if(scanf("%d", &num) != 1) return 1;
start_num = num; //Save the original value.
//Determine the prime factors of a number
for(i = 2; i <= num; i++) { //Loop to check the factors.
while(num % i == 0) { //While the input is divisible to "i" which is initially 2.
if(!is_first) printf("x "); //Print the operator before second and later operands.
printf("%d ", i); //Print the factor.
num = num / i; //Divide the num by "i" which is initially 2 to change the value of num.
is_first = 0; //Mark that there is already one or more operand.
}
}
printf("= %d\n", start_num); //Print the original value.
return 0;
}
You can output the factors with the appropriate punctuation:
// Output the prime factors of a number
void factorize(int num) {
int n = num; // save the initial value of num
const char *sep = ""; // initial separator is an empty string
for (int i = 2; i <= num / i; i++) { // stop when num is reduced to a prime
while (num % i == 0) { // while the input is divisible to "i"
num = num / i; // divide the num by "i" (remove the factor)
printf("%s%d", sep, i); // print the separator and the factor.
sep = " x "; // change the separator for any further factors
}
}
if (num > 1 || n <= 1) {
printf("%s%d", sep, num); // print the last or single factor.
}
printf(" = %d\n", n); // print the rest of the equation
}
I've revised the code to give something that's a bit more robust than what I posted previously, as well as being slightly more efficient. Again I assume you want (unsigned) 32-bit input via stdin in the range: [1, 2^32 - 1]
As far as the algorithm is concerned, it should be apparent that searching for factors need only test candidates up to floor(sqrt(num)). There are also factors with multiplicity, e.g., (24) => {2, 2, 2, 3}.
Furthermore, after factoring out (2), only odd factors need to be tested.
For a 32-bit (unsigned) type, there will be fewer than (32) prime factors. This gives a simple upper-bound for a fixed-size array for storing the successive prime factors. The prime factors in the array are in ascending order, by virtue of the algorithm used.
/******************************************************************************/
#include <stdio.h>
int main (void)
{
/* print a value in [1, 2^32 - 1] as a product of primes: */
unsigned long int n, u, prime[32];
int np = 0;
if (scanf("%lu", & n) != 1 ||
((n == 0) || ((n & 0xffffffffUL) != n)))
{
fprintf(stderr, "factor < u32 = 1 .. 2^32 - 1 >\n");
return (1);
}
if (n == 1) /* trivial case: */
{
fprintf(stdout, "1 = 1\n");
return (0);
}
u = n; /* (u) = working value for (n) */
for (; (u & 0x1) == 0; u >>= 1) /* while (u) even: */
prime[np++] = (2);
while (u > 1)
{
unsigned long q, d = 3, c = 0; /* (c)omposite */
if (np != 0) /* start at previous odd (prime) factor: */
d = (prime[np - 1] == 2) ? (3) : prime[np - 1];
for (; (c == 0) && (q = u / d) >= d; )
{
if ((c = (q * d == u)) == 0) /* not a factor: */
d += 2;
}
prime[np++] = (d = (c == 0) ? u : d);
u /= d; /* if (u) is prime, ((u /= d) == 1) (done) */
}
for (int i = 0; i < np; i++)
{
const char *fmt = (i < np - 1) ? ("%lu x ") : ("%lu = ");
fprintf(stdout, fmt, prime[i]);
}
fprintf(stdout, "%lu\n", n);
return (0);
}
/******************************************************************************/

finding prime numbers between a range in C

I am trying to find the prime numbers in a range using C language. My code does not give an output and I think there is a logical error here which I cannot figure out. Can anyone please help?
#include <stdio.h>
int main() {
int lowerLevel;
int upperLevel;
int i; //counter variable
int prime = 0;
int flag = 0;
printf("Enter the lower limit and upper limit of the range followed by a comma :");
scanf("%d %d", &lowerLevel, &upperLevel);
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
}
Your code does not check for prime numbers, it merely checks that there is at least one even number between 2 and upperlevel, which is true as soon as upperlevel >= 2. If there is such an even number, nothing is printed.
You should instead run a loop from lowerlevel to upperlevel and check if each number is a prime and if so, print it.
Here is a modified version:
#include <stdio.h>
int main() {
int lowerLevel, upperLevel;
printf("Enter the lower limit and upper limit of the range: ");
if (scanf("%d %d", &lowerLevel, &upperLevel) != 2) {
return 1;
}
for (int i = lowerLevel; i <= upperLevel; ++i) {
int isprime = 1;
for (int p = 2; p <= i / p; p += (p & 1) + 1) {
if (i % p == 0) {
isprime = 0;
break;
}
}
if (isprime) {
printf("%d ", i);
}
}
printf("\n");
return 0;
}
This method is simplistic but achieves the goal. More efficient programs would use a sieve to find all prime numbers in the range without costly divisions.
Optimal method with Sieves of Eratosthenes
You should use the sieves of Eratostenes algorithm, it is way more efficient to get the different prime number.
it does so by iteratively marking as composite (i.e., not prime) the multiples of each prime, starting with the first prime number, 2
Basically you consider all numbers prime by default, and then you will set as false the prime number, see below code:
#include <stdio.h>
/// unsigned char saves space compared to integer
#define bool unsigned char
#define true 1
#define false 0
// https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
void printPrimesRange(int lowerLevel, int n) {
if (lowerLevel < 0 || n < lowerLevel) // handle misused of function
return ;
bool isPrime[n + 1];
memset(isPrime, true, n + 1);
int cnt = 0; // NB: I use the counter only for the commas and final .\n, its optional.
if (lowerLevel <= 2 && n >= 2) { // only one even number can be prime: 2
++cnt;
printf("2");
}
for (int i = 3; i <= n ; i+=2) { // after what only odd numbers can be prime numbers
if (isPrime[i]) {
if (i >= lowerLevel) {
if (cnt++)
printf(", ");
printf("%d", i); // NB: it is better to print all at once if you can improve it
}
for (int j = i * 3; j <= n; j+=i*2) // Eratosthenes' Algo, sieve all multiples of current prime, skipping even numbers
isPrime[j] = false;
}
}
printf(".\n");
}
int main(void) {
int lowerLevel;
int upperLevel;
printf("Enter the lower limit and upper limit of the range with a space in-between:"); // space, not comma
scanf("%d %d", &lowerLevel, &upperLevel);
printPrimesRange(lowerLevel, upperLevel);
return 0;
}
Let's follow the logic of your code:
#include <stdio.h>
#include <string.h>
int main() {
int lowerLevel;
int upperLevel;
int i; //counter variable
int prime = 0;
int flag = 0;
printf("Enter the lower limit and upper limit of the range followed by a comma :");
scanf("%d %d", &lowerLevel, &upperLevel);
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
}
First of all, you have a loop:
for (i = 2; i <= upperLevel; ++i) {
if (i % 2 == 0) {
flag = 1;
break;
}
}
this loop tries to find a number i that is a multple of 2, because as soon you get one, you jump out of the loop. So your loop can be expressed better as:
for (i = 2; i <= upperLevel && i % 2 != 0; ++i) {
}
/* i > upperLevel || i % 2 == 0 */
if (i <= upperLevel && i % 2 == 0) {
flag = 1;
}
We still need to check if i <= upperLevel && i % 2 == 0 to set the variable flag = 1 if we exited the loop because i was a multiple of 2, but the break; is not necessary because we are already out of the loop.
Now let's check that the first value we initialize i is, indeed 2 (which is a multiple of 2) and the consecuence of this is that the loop is never going to be entered. Se we can eliminate it completely, giving to:
i = 2;
if (i <= upperLevel && i % 2 == 0) {
flag = 1;
}
now, the second clause of the if test is always true, so we can take it off, giving:
i = 2;
if (i <= upperLevel) {
flag = 1;
}
Now, let's append the second part:
i = 2;
if (i <= upperLevel) {
flag = 1;
}
if (flag == 0) {
printf("%d", i);
++i;
}
return 0;
so, the first thing we see here is that your ++i; statement is nonsense, as it is the last statement to be
executed before exiting the program, so we can also take it off.
i = 2;
if (i <= upperLevel) {
flag = 1;
}
if (flag == 0) {
printf("%d", i);
}
return 0;
Now we see that you print the value of i only if the value of flag is zero, but flag only conserves its zero value if the value of i > upperLevel, and as i is fixed, the printing of i only occurs if you input a value of upperlevel that is less than 2.
We can rewrite the above code as this:
if (2 > upperLevel) {
printf("%d", 2);
}
Your program will print 2 only if you provide a value of upperLevel less than 2.

Not able to understand how values in loop work

I tried writing code for cs50 pset1's problem: credit.c(more comfortable) after week2. My code is given below. The problem is that 'sumx' and 'sumy' are just 0 and hence 'sum' is always equal to 0. So whenever I give a correct credit card number, it is just going to new line and program ends. How can I solve this problem and why are 'sumx' and 'sumy' not adding up to their respective sums as they should according to the algorithm?
My code is:
#include <cs50.h>
#include <stdio.h>
int main(void){
long long i;
do{
printf("Your credit card number:\n");
i = get_long_long();
}
while(i < 4e12 || i > 5.5e15);
int count = 0;
int n;
long long c = i;
while(i != 0){
n = i%10;
i = i/10;
count++;
}
int x[count];
for(int j = 0; j < count; j++){
x[j] = c%10;
i = c/10;
}
int sumx = 0;
for(int j = 0; j < count - 1; j += 2){
x[j] = x[j] * 2;
sumx = sumx + x[j];
printf("%i", sumx);
}
int sumy = 0;
for(int j = 0; j < count; j += 2){
sumy = sumy + x[j];
}
int sum;
sum = sumx + sumy;
if(sum%10 == 0){
if((count == 15 && x[14] == 3) && (x[13] == 4 || x[13] == 7)){
printf("AmEx\n");
}
else if((count == 16 && x[15] == 5) && (x[14] > 1 || x[14] < 5)){
printf("MASTERCARD\n");
}
else if((count == 13 && x[12] == 4) || (count == 16 && x[15] == 4)){
printf("VISA\n");
}
}
else{
printf("Invalid Number\n");
}
return 0;
}
//#include <cs50.h>
#include <stdio.h>
int main(void){
long long i=4111111111111111;
//Master: 5105105105105100;//16
//visa: 4111111111111111
printf("%lld\n",i);
//~ do{
//~ printf("Your credit card number:\n");
//~ i = get_long_long();
//~ }
//~ while(i < 4e12 || i > 5.5e15);
int count = 0;
long long c = i;
int k=0;
int x[100];//
while(c != 0){
x[k] = c%10;
c = c/10;
printf("%lld\n",c);
count++;
k++;
}
//k==count
printf("count:%d\n",count);
printf("k:%d\n",k);
// x[i] contains all the digits of credit card
printf("print x[i]\n");
for (int i=0;i<count;i++){
printf("%d ",x[i]);
}
printf("\n");
int addsum=0,x2prod=0;
for (int j=0; j<k; j+=2 ){
addsum += x[j];
}
printf("addsum:%d\n",addsum);
for (int j=1; j<k; j+=2 ){
if ( (2 * x[j]) > 9 ){ //have 2 digit
x2prod += (2 * x[j]) / 10;
x2prod += (2 * x[j]) % 10;
}
else // have one digit
x2prod += 2 * x[j];
}
printf("x2prod:%d\n",x2prod);
int sum;
sum = addsum + x2prod;
printf("\nsum: %d\n",sum);
if(sum%10 == 0){
if((count == 15 && x[14] == 3) && (x[13] == 4 || x[13] == 7)){
printf("AmEx\n");
}
else if((count == 16 && x[15] == 5) && (x[14] > 1 || x[14] < 5)){
printf("MASTERCARD\n");
}
else if((count == 13 && x[12] == 4) || (count == 16 && x[15] == 4)){
printf("VISA\n");
}
}
else{
printf("Invalid Number\n");
}
return 0;
}
I apply some correction on your code, store all credit card digits on x[]array in first while().
I checked code output with only three samples and by the way this is not a reliable version, try to catch any error.
As you read on my comment i don't any idea about that, but by perform simple search this link
show me what to do and decode it to your way.

writing a prime factorization program C

I am trying to write a program that shows the results of prime factorization as below:
prompt: Input a positive integer
result examples:
100 = 2^2*5^2
It is a composite integer !
13 = 13
It is a prime number !
I tried to write it only with the basic loops, not using sophisticated techniques because it was for beginner's class. The problem is that when I enter 100 as an input, the result is just
100 =
being printed and the program stops there. Other than that, it gives me results I intended. Can anyone help me find what part of this code is the problem?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int inputNumber (int* input);
int primeFactors (int input);
int main (void) {
int input;
while ( 1 ) {
inputNumber (&input);
primeFactors (input);
}
return 0;
}
int inputNumber (int* input){
printf("\nInput a positive integer : ");
scanf("%d", input);
if(*input == 0){
printf("\n End of program");
exit(0);
}
return;
}
int primeFactors (int input){
int cnt = 0, i = 3, cnt_sum;
printf("%d = ", input);
if(input > 0){
while ( input % 2 == 0){
cnt++;}
if(cnt == 1){
printf("%d",2);}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",2,cnt);
}
cnt_sum += cnt;
for ( ; i <= sqrt(input); i = i+2){
cnt = 0;
while(input % i == 0){
cnt++;
input /= i;
}
if(cnt == 1){
printf("%d",i);
}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",i,cnt);
}
cnt_sum += cnt;
}
if(cnt_sum > 1){
printf("\nIt is a composite number !\n");
}
else{
printf("%d\nIt is a prime number !\n",input);
}
}
else{
printf("\nIt is an invalid number !\n");
}
}
There were few bugs.
while ( input % 2 == 0){cnt++;} loops infinitely if input is even( #Marian )
if(input > 1){ instead of if(input > 0){. since 1 is neither prime nor composite.
Corrected function:
int primeFactors (int input){
int cnt = 0, i = 3, cnt_sum;
printf("%d = ", input);
if(input > 1){
while ( input % 2 == 0){
input/=2;
cnt++;
}
if(cnt == 1){
printf("%d",2);}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",2,cnt);
}
cnt_sum += cnt;
for ( ; i <= sqrt(input); i = i+2){
cnt = 0;
while(input % i == 0){
cnt++;
input /= i;
}
if(cnt == 1){
printf("%d",i);
}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",i,cnt);
}
cnt_sum += cnt;
}
if(cnt_sum > 1){
printf("\nIt is a composite number !\n");
}
else{
printf("%d\nIt is a prime number !\n",input);
}
}
else{
printf("\nIt is an invalid number !\n");
}
}
ideone
You seem to be missing some steps in your algorithm, as well as checking redundant conditions in your primeFactors function.
int cnt = 0, i = 3, cnt_sum;
Because these won't ever be negative, you can change the type to unsigned.
while ( input % 2 == 0){
cnt++;
}
This while statement will loop infinitely if input is odd, because nothing is done to change input. You can add input = input / 2; to stop this.
if(cnt == 1){
printf("%d",2);}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",2,cnt);
}
The else if expression can be reduced to an else statement, because unsigned variables are always greater than 0 and we already know cnt != 1, otherwise the first statement would be triggered.
while(input % i == 0){
cnt++;
input /= i;
}
The while statement is all good here, how peculiar. :P
if(cnt == 1){
printf("%d",i);
}
else if( cnt > 0 && cnt != 1){
printf("%d^%d",i,cnt);
}
Same deal here as with the if / else if statements before: change the else if to else.
With these corrections applied (and some style inconsistencies fixed), the function now looks like this:
int primeFactors (int input) {
unsigned cnt = 0, i = 3, cnt_sum;
printf("%d = ", input);
if (input > 0) {
while (input % 2 == 0) {
cnt++;
input /= 2;
}
if (cnt == 1) {
printf("%d", 2);
} else {
printf("%d^%d", 2, cnt);
}
cnt_sum += cnt;
for ( ; i <= sqrt(input); i += 2){
cnt = 0;
while (input % i == 0) {
cnt++;
input /= i;
}
if (cnt == 1) {
printf("%d", i);
} else {
printf("%d^%d", i, cnt);
}
cnt_sum += cnt;
}
if (cnt_sum > 1) {
printf("%d\nIt is a composite number !\n");
} else {
printf("%d\nIt is a prime number !\n",input);
}
}
else{
printf("\nIt is an invalid number !\n");
}
}

Primes less than an integer

I wrote a program to find all primes less that a user-input integer. However, it just hangs. I assume using all these continues and whatnot is a mess and I have made spaghetti code...can anyone help me?
/*takes integer input, displays all primes less than that integer*/
#include <stdio.h>
int main(void) {
unsigned int num_in, test_num = 0, divisor = 0;
_Bool primestate = 0;
printf("Please enter an integer.\n");
scanf("%d", &num_in);
while(test_num < num_in) {
while(divisor < test_num) {
if(test_num % divisor == 0) {
primestate = 1;
}
test_num++;
}
if(primestate == 1) {
printf("%d is prime and less than %d.\n", test_num, num_in);
} else {
continue;
}
}
return 0;
}
You never increment test_num or divisor, so it gets stuck in one of the loops.
while(test_num < num_in) {
while(divisor < test_num) {
if(test_num % divisor == 0) {
primestate = 1;
}
divisor++; // NEW LINE
}
if(primestate == 1) {
printf("%d is prime and less than %d.\n", test_num, num_in);
} else {
continue;
}
test_num++; // NEW LINE
}
You also have a possible division by 0 (when divisor equals 0) on this line:
if(test_num % divisor == 0) {
#include <stdio.h>
#include <stdbool.h>
int main(void) {
unsigned int num_in, test_num, divisor;
bool primestate;
printf("Please enter an integer.\n");
scanf("%u", &num_in);
if(2 < num_in)
printf("\n%u\n", 2);
for(test_num = 3; test_num < num_in; test_num += 2){
primestate = true;
for(divisor=3; divisor * divisor <= test_num ; divisor += 2) {
if(test_num % divisor == 0) {
primestate = false;
break;
}
}
if(primestate) {
printf("%u\n", test_num);
}
}
return 0;
}

Resources