Problems with printing output C - c

So I have to write a code for school. I did, but my outputs are not the way they asked for. This code gives me prime number between 2 different numbers. So i have to print those numbers in rows. But yeah there are getting zeros between the answers below you can see what I mean. How can I fix this?
#include <stdio.h>
int is_prime (int number)
{
int is_prime= 1, i;
if (number < 2)
{
is_prime = 0;
}
else
{
for(i = 2; (i * i) <= number; i++)
{
if ((number % i) == 0)
{
is_prime = 0;
break;
}
else
{
is_prime = 1;
}
}
}
return is_prime;
}
int main (void)
{
int lower_limit, upper_limit, i;
scanf("%d\n%d", &lower_limit, &upper_limit);
for(i = lower_limit; i <= upper_limit; i++)
{
if (is_prime (i))
{
printf("\n%d", i);
}
else
{
printf("\n%d", is_prime(i));
}
}
return 0;
}
Output
0
11
0
13
0
0
0
17
0
19
0
Reference
11
13
17
19

It's in this if block:
if (is_prime (i))
{
printf("\n%d", i);
}
else
{
printf("\n%d", is_prime(i));
}
What this says is "if the number is prime print it, otherwise print whether it is prime (which at this point you've established it's not)".
Just get rid of the else block.

If the number is prime number just print it. No else needed - even worse it is incorrect.
You can simplyfy the the is_prime function
int is_prime (int number)
{
int is_prime = number > 1, i;
for(i = 2; (i * i) <= number; i++)
{
if ((number % i) == 0)
{
is_prime = 0;
break;
}
}
return is_prime;
}
int main (void)
{
int lower_limit, upper_limit, i;
scanf("%d\n%d", &lower_limit, &upper_limit);
for(i = lower_limit; i <= upper_limit; i++)
{
if (is_prime (i))
{
printf("\n%d", i);
}
}
return 0;
}
https://godbolt.org/z/4d8qhx

Another problem: overflow.
Avoid int overflow in i*i, which is undeifned behavior (UB).
This can happen when number is a prime near INT_MAX.
// for(i = 2; (i * i) <= number; i++)
for(i = 2; i <= number/i; i++)
A good compiler will see the nearby number%i and number/i and emit efficient code for the two of them, thus not incurring an expensive 2nd operation.
The below also overflows when upper_limit == INT_MAX
for(i = lower_limit; i <= upper_limit; i++)
Perhaps
for(i = lower_limit; i - 1 < upper_limit; i++)
OK as long as lower_limit > INT_MIN.

Related

Print Prime Numbers and Reversed Number

A number and a reversed number form a pair. If both numbers are prime numbers, we call it a reversed prime number pair. For instance, 13 and 31 is a 2 digit reversed prime number pair, 107 and 701 is a 3 digit reversed prime number pairs.
Write a program to output all n (2<=n<=5) digit reversed prime number pairs. If the input is less than 2 or greater than 5, output "Wrong input." and terminate the program. While ouputting , every 5 pairs form a new line, and only output the pair in which the first number is smaller than the second number.
Input: 1
Output: Wrong input.
Input: 3
Output:
(107,701)(113,311)(149,941)(157,751)(167,761)
(179,971)(199,991)(337,733)(347,743)(359,953)
(389,983)(709,907)(739,937)(769,967)
There are 14 results.
Can anyone give me hints how to do this?
I know how to determine if a number is a reversed prime number, but i couldn't understand how to complete this challenge from my friend
#include <stdio.h>
int checkPrime(int n) {
int i, isPrime = 1;
if (n == 0 || n == 1) {
isPrime = 0;
}
else {
for(i = 2; i <= n/2; ++i) {
if(n % i == 0) {
isPrime = 0;
break;
}
}
}
return isPrime;
}
int main (void)
{
int a, reverse = 0, remainder, flag=0;
scanf("%d",&a);
int temp = a;
while (temp!=0) {
remainder = temp%10;
reverse = reverse*10 + remainder;
temp/=10;
}
if (checkPrime(a)==1) {
if (checkPrime(reverse)==1){
printf("YES\n");
flag=1;
}
}
if (flag==0)
printf("NO\n");
}
This will be the correct solution:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <stdlib.h>
#define MAX_N 100000
int *primes;
int num_primes;
void init_primes() {
int sqrt_max_n = sqrt(MAX_N);
primes = (int *) malloc(sqrt_max_n / 2 * sizeof(int));
num_primes = 0;
primes[num_primes] = 2;
num_primes++;
for (int i = 3; i <= sqrt_max_n; i += 2) {
bool is_prime = true;
for (int j = 0; j < num_primes; j++) {
if (i % primes[j] == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
primes[num_primes] = i;
num_primes++;
}
}
}
int is_prime(int n) {
for (int i = 0; i < num_primes; i++) {
if (primes[i] == n) {
return 1;
}
if (n % primes[i] == 0) {
return 0;
}
}
return 1;
}
int reverse(int n) {
int reversed_n = 0;
while (n > 0) {
reversed_n = reversed_n * 10 + n % 10;
n /= 10;
}
return reversed_n;
}
int main() {
init_primes();
int n;
printf("Enter n (2 <= n <= 5): ");
scanf("%d", &n);
if (n < 2 || n > 5) {
printf("Wrong input.\n");
return 0;
}
int min = (int) pow(10, n - 1);
int max = (int) pow(10, n) - 1;
int count = 0;
for (int i = min; i <= max; i++) {
if (is_prime(i)) {
int reversed_i = reverse(i);
if (i < reversed_i && is_prime(reversed_i)) {
printf("(%d %d)", i, reversed_i);
count++;
if (count % 5 == 0) {
printf("\n");
} else {
printf(" ");
}
}
}
}
return 0;
}
After testing this code I get the same result what you need:
Enter n (2 <= n <= 5): 3
(107 701) (113 311) (149 941) (157 751) (167 761)
(179 971) (199 991) (337 733) (347 743) (359 953)
(389 983) (709 907) (739 937) (769 967)
The init_primes method caches all the required prime numbers until the sqrt of your limit to a dynamic array.
The is_prime method uses that cache for detecting whether a number is prime or not.

ReArrange a number with ascending digits

I have to solve a problem where one of the important tasks is to reorder the digits of the input in ascending order and we are not allowed to use arrays and lists. I have no problem with that and my code works, but only if we do not consider leading 0, which we should in this problem. The only way I see how to do is to check digit by digit and then add then ordered by multiplying the number by 10 and adding the next digit. (1*10 = 10, 10+3= 13, we got 1 and 3 ordered) However, if we have a 0 in our number this method will not work because if I want to make 0123 with the * 10 method, I won't be able to have the 0 as the first digit never. Does anyone know how to solve this? My code is below:
int ascendingNumbers (int n) { //This function sorts the number on an ascending order
int number = n;
int sortedN = 0;
for (int i = 0; i <= 9; i++) {
int toSortNumber = number;
for (int x = 0; x <= 4; x++) {
int digit = toSortNumber % 10;
if (digit == i) {
if (digit == 0) {
sortedN==10;
}
sortedN *= 10;
sortedN += digit;
}
toSortNumber /= 10;
}
}
return sortedN;
}
Normally I don't do homework problems, but for especially awful ones I'll make an exception.
(Also I'm making an exception to my general rule not to have anything to do with these absurd "desert island" constraints, where you're stranded after a shipwreck and your C compiler's array functionality got damaged in the storm, or something.)
I assume you're allowed to call functions. In that case:
#include <stdio.h>
/* count the number of digits 'd' in 'n'. */
int countdigits(int n, int d)
{
int ret = 0;
/* do/while so consider "0" as "0", not nothing */
do {
if(n % 10 == d) ret++;
n /= 10;
} while(n > 0);
return ret;
}
int main()
{
int i, n;
printf("enter your number:\n");
scanf("%d", &n);
printf("digits: ");
for(i = 0; i < 10; i++) {
int n2 = countdigits(n, i);
int j;
for(j = 0; j < n2; j++) putchar('0' + i);
}
printf("\n");
}
This solution does not involve a function int ascendingNumbers() as you asked about. If you want to handle leading zeroes, as explained in the comments, you can't do it with a function that returns an int.
Your zero problem is solved, check it...
class Main {
public static void main(String[] args) {
int number = 24035217;
int n = number, count = 0;
int sortedN = 0;
while (n != 0) {
n = n / 10;
++count;
}
for (int i = 9; i >= 0; i--) {
int toSortNumber = number;
for (int x = 1; x <= count; x++) {
int digit = toSortNumber % 10;
// printf("\nBefore i = %d, x = %d, toSortNumber = %d, sortedN = %d, digit = %d",i,x,toSortNumber,sortedN,digit);
if (digit == i) {
sortedN *= 10;
sortedN += digit;
}
// printf("\nAfter i = %d, x = %d, toSortNumber = %d, sortedN = %d, digit = %d",i,x,toSortNumber,sortedN,digit);
toSortNumber /= 10;
}
}
System.out.print(sortedN);
}
}

C- Function that compares two four digit number arrays

I'm trying to create a function that compares two four digit numbers and
returns the number of similar digits between the two. For example, with a generated number of 4311 and the user entered 1488,
the score should return 2 (4 and 1).
If it was 4311 and the other is 1147,
the score should return three (1, 1 and 4). I don't know why it isn't giving me the right outputs, hope you can help.
int getSameDigitScore(int playerGuess, int generatedNum) {
int score = 0;
int i;
int j;
int k;
int generatedNumArray[4];
int playerGuessArray[4];
// turns playerGuess into an array
while (playerGuess > 0 ) {
i = 0;
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
// turns generatedNum into an array
while (generatedNum > 0) {
i = 0;
generatedNumArray[i] = generatedNum % 10;
i++;
generatedNum /= 10;
}
// compares the two arrays
for (k = 3; k >= 0; k--) {
for (j = 3; j >= 0; j--) {
if (generatedNumArray[k] == playerGuessArray[j]) {
score++;
playerGuessArray[j] = 0;
j = -5;
}
}
}
return score;
}
You are assigning i = 0 inside the while loop while generating the playerGuessArray and generatedNumArray. Due to which the playerGuess and generatedNumArray array will have elements as first digit of your number 0 0 0 .
Move the initialization out of the loop.
int getSameDigitScore(int playerGuess, int generatedNum) {
int score = 0;
int i, j, k, n;
int generatedNumArray[4];
int playerGuessArray[4];
// turns playerGuess into an array
i = 0; // This has been out of while loop
while (playerGuess > 0 ) {
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
// turns generatedNum into an array
int n = 0; // This has been out of the while loop
while (generatedNum > 0) {
generatedNumArray[n] = generatedNum % 10;
n++;
generatedNum /= 10;
}
// compares the two arrays
for (k = 3; k >= 0; k--) {
for (j = 3; j >= 0; j--) {
if (generatedNumArray[k] == playerGuessArray[j]) {
score++;
playerGuessArray[j] = 0;
j = -5;
}
}
}
return score;
}
int main() {
int m;
n = getSameDigitScore(1231, 2342);
printf("Score is: %d\n", m);
}
You're re-initializing increment variable i on every iteration which should be moved out of the while loop. With that moved out the above code works fine.
There are the following issues with the code.
You are initializing the integer i inside the while loop. This needs to be done before the loop for each loop.
You need a separate array to get the output of equal digits. See AnswerArray in code below. Also it is a good design practice to pass this array to the function and clear this array inside the function.
In the last for loop, you should break from the inner loop after getting a match. This is to take care of cases where playerGuess == 1222 and generatedNum = 1111 In the code shown this will result in a score of 1.
See the final code below with some test cases.
int getSameDigitScore(int playerGuess, int generatedNum, int *AnswerArray) {
int score = 0;
int i;
int j;
int k;
int generatedNumArray[4] = {0};
int playerGuessArray[4] = {0};
memset(AnswerArray,0,4*sizeof(int));
// turns playerGuess into an array
i = 0;
while (playerGuess > 0 ) {
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
// turns generatedNum into an array
i = 0;
while (generatedNum > 0) {
generatedNumArray[i] = generatedNum % 10;
i++;
generatedNum /= 10;
}
// compares the two arrays
score=0;
for (k = 3; k >= 0; k--) {
for (j = 3; j >= 0; j--) {
if (generatedNumArray[k] == playerGuessArray[j]) {
AnswerArray[score++] = generatedNumArray[k];
playerGuessArray[j] = -1;
break;
}
}
}
return score;
}
int main(void)
{
int AnswerArray[4],score;
score = getSameDigitScore(4311,1488,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
score = getSameDigitScore(4311,1147,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
score = getSameDigitScore(1222,1111,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
score = getSameDigitScore(1111,1222,AnswerArray);
printf ("\nScore = %d \n Answer Array = ",score);
for (int i=0; i<score; i++)
{
printf ("%d ",AnswerArray[i]);
}
}
The initializing i=0 which you made inside the loop should be outside the loop.
while (playerGuess > 0 ) {
i = 0;
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
If the initialization is inside the looop then,
Everytime playerGuessArray[0] value will be updated.
FYI:
If playerGuess can contain 0 aat the begin of four digit like 0123
For example, playerGuessValue is 0123, Then by using
while (playerGuess > 0 ) {
i = 0;
playerGuessArray[i] = playerGuess % 10;
i++;
playerGuess /= 10;
}
playerGuessArray will contain only [1,2,3] instead of [0,1,2,3].
So, the better solution would be taking two temporary variables and checking last digit one by one.
Like this:
int temp1=playerGuess, temp2=GeneratedNum;
int i=0;
bool flag = true;
while(flag && i < 4){
if(temp1%10 != temp2%10){
flag = false;
}
temp1 /= 10;
temp2 /= 10;
i++;
}
if(flag){
score++;
}
FYI:
Debugging will help you in finding out these little mistakes.So, try to debug your code with multiple inputs and verify your answer.
Here are few reference on how to debug:
https://blog.hartleybrody.com/debugging-code-beginner/
https://www.codementor.io/mattgoldspink/how-to-debug-code-efficiently-and-effectively-du107u9jh%60
Thanks.

Sieve of Eratosthenes and his primes

This is my code:
#include <stdio.h>
int main() {
int number;
int prime[200000] = { 0 };
int i = 0;
int j = 0;
int number1[200] = { 0 };
int t = 0;
int count = 0;
int newprime2[200][200];
int counter[200] = { 0 };
int square;
int count1;
while ((scanf("%d", &number) == 1 ) && (number != 0)) {
number1[count] = number;
++count;
}
count1 = count;
for (count = 0; count < count1; ++count) {
if (number1[count] < 0) {
fprintf(stderr, "Error: Invalid input!\n");
return 100;
break;
}
for (i = 0; i < number1[count]; i++) {
prime[i] = i;
}
for (i = 2; (i < (number1[count])); i++) {
if (prime[i] != 0) {
for (j = 2; (j < (number1[count])); j++) {
{
prime[j*prime[i]] = 0;
if (prime[i] * j > (number1[count]))
break;
}
}
}
}
t = 0;
for (i = 2; i < number1[count]; ++i) {
if ((prime[i] != 0) && (number1[count] % prime[i] == 0)) {
newprime2[count][t] = prime[i];
++t;
}
}
printf("\n");
printf("%i is made out of these primes\n", number1[count]);
counter[count] = 0;
square = 0;
for (i = 0; i < t; ++i) {
while (number1[count] % newprime2[count][i] == 0) {
number1[count] = number1[count] / newprime2[count][i];
square++;
}
counter[count]++;
/* if number isn't made out of any of these primes*/
if (!newprime2[count][i]) { /*Why is this not working?*/
printf("%i ", number1[count]);
}
if (counter[count] == 1) {
printf("%i^%d ", newprime2[count][i], square);
} else {
printf("* %i^%d ", newprime2[count][i], square);
}
square = 0;
}
}
printf("\n");
return 0;
}
For example, my input is: 1 11 120 8 0
Output looks like this:
1 is made out of these primes
11 is made out of these primes
120 is made out of these primes
2^3 * 3^1 * 5^1
8 is made out of these primes
2^3
But Output should looks like this:
1 is made out of these primes
1
11 is made out of these primes
11
...
Statement (!newprime2[count][i]) means that this array is empty right? So why it isn't working? And why I even can't use gcc -pedantic -Wall -Werror -std=c99 -O3 ? Can someone help me?
See this part of your code:
t = 0;
for (i = 2; i < number1[count]; ++i){
if ((prime[i]!=0) && (number1[count] % prime[i]==0)){
newprime2[count][t] = prime[i];
++t;
}
If number1[count] is 1, then the body of the for loops will not execute, sot will keep its value (0). Consequently the body of the next loop
for (i=0; i < t; ++i){
will not execute, too.
For number 11 the body of this loop will execute but it will do nothing as the condition in the if statement will be always false. So it results to the same problem - t will keep its value 0 with the same consequence.
The line
if (!newprime2[count][i])
is not reached if t==0 before the for-loop and that is the case if the input is prime or unity. Just check t and end there if it is zero.
Or check earlier if it is unity or it is in prime already.
I cannot repeat your problems with gcc -pedantic -Wall -Werror -std=c99 -O3.
Your algorithm is both too complicated and approximate:
You do not need to perform a sieve to factorize the numbers, you can just enumerate divisors, composite divisors will have a non zero remainder because their prime factors will have been removed already.
The sieve is incomplete: you go to 200000 which would be overkill if int type is 32 bits (46341 would suffice) and would be too small if int is 64 bits.
Here is a simplified version:
#include <stdio.h>
int main(void) {
int number, i, p, n, factors, count;
int numbers[200];
for (count = 0; count < 200 && scanf("%d", &number) == 1; count++) {
if (number == 0)
break;
if (number < 0) {
fprintf(stderr, "Error: Invalid input!\n");
return 100;
}
numbers[count] = number;
}
for (i = 0; i < count; i++) {
number = numbers[i];
printf("%d is made out of these primes\n", number);
factors = 0;
for (p = 2; p * p <= number; p += 1 + (p & 1)) {
if (number % p == 0) {
n = 0;
factors++;
do {
number /= p;
n++;
} while (number % p == 0);
if (n == 1)
printf("%d ", p);
else
printf("%d^%d ", p, n);
}
}
if (factors == 0 || number != 1)
printf("%d", number);
printf("\n");
}
return 0;
}

Why this reverse function can not work in the for loop?

#include <stdio.h>
#include <math.h>
int prime (long n);
long reverse(long n);
int main(void)
{
long n;
long i, j;
puts("Enter n dight number, and we will help you find symmetrical prime number");
scanf("%ld", &n);
for (i = 11; i < (pow(10, n) - 1); i+= 2)
{
if (prime(i))
{
j = reverse(i);
if (i == j)
{
printf("%ld\n", i);
}
}
}
}
int prime (long n) //estimate whether the number n is primer number
{
int status = 0;
int j;
//1 is prime, 0 is not
if (n % 2 == 0 || n == 3)
{
if (n == 2)
status = 1;
if (n == 3)
status = 1;
else
{
n++;
status = 0;
}
}
else
{
j = 3;
while (j <= sqrt(n))
{
if (n % j == 0)
{
status = 0;
break;
}
else
status = 1;
j+= 2;
}
}
return status;
}
long reverse(long n) //reverse a number
{
int i, j, x;
long k, sum;
int digit = 0;
int ar[1000];
while (n > 0)
{
k = n;
n = n / 10;
x = (k - n*10);
digit++;
ar[digit] = x;
}
for (i = 1,j = digit - 1; i <= digit; i++, j--)
{
sum += ar[i] * pow(10, j)
}
return sum;
}
I build a reverse function in order to reverse numbers, for example, 214, to 412.
This function works fine in individual number, for instance, I type reverse(214), it return 412, which is good. But when I combine reverse() function with for loop, this function can not work... it produces some strange number...
so How can I fix this problem?
The reverse function is extremely complicated. The better way to go about it would be:
long reverse (long n)
{
long result = 0;
while (n != 0)
{
result *= 10;
result += n % 10;
n /= 10;
}
return result;
}
I think the problem in your code is that in the following segment
digit++;
ar[digit] = x;
you first increment the position then assign to it, thus leaving ar[0] unintialized.
How can I fix this problem?
You need to initialize sum
long k, sum = 0;
^
See the code from #Armen Tsirunyan for a simpler approach.

Resources