Weird Output in for loop in C (Repetitive numbers) - c

This is my code for finding prime numbers.
int main (void){
int p, d;
_Bool isprime;
for (p=2;p<=50;++p){
isprime = 1;
for (d=2;d<p;++d){
if (p%d == 0)
isprime = 0;
if (isprime != 0)
printf("%i ", p);
}
}
return 0;
}
The output of this program is
3 5 5 5 7 7 7 7 7 9 11 11 11 11 11 11 11 11 11 13 13 13 13 13 13 13 13 13 13 13 15 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 19 21 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 25 25 25 27 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 29 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 31 33 35 35 35 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 39 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 43 45 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 47 49 49 49 49 49
The numbers seem to be right, but they are repetitive. Is there something wrong with my code? Or is there something wrong with the compiler? Every time I use a for loop (not just this program) the output is like this. How do I fix this?
Thanks in advance!(Sorry for my bad English)

The problem with your code, is that it prints p multiple times, for the same value of p. Like Eugene Sh. stated in a comment, it's easily fixed by moving the if statement up a level, to the outer for loop. I also changed is_prime to a bool value, and edited how it's set.
int max_p = 50;
int p, d;
bool is_prime;
for (p = 2; p <= max_p; ++p) {
is_prime = true;
for (d = 2; d < p; ++d) {
if (p % d == 0) {
is_prime = false;
break;
}
}
if (is_prime) {
printf("%i ", p);
}
}
I will assume that I used C++ doesn't make a difference.

Others have given tips. Some of them are useful, some of them are not. The end goal is to print all prime numbers only. So checking if the number 6 is prime, we start with d = 2. So we check 6 % 2. Well that is equal to 0. We know that 6 is NOT prime. We should move on to 7. Instead we have incremented 2 to 3 and now we check again. 6 % 3... we do this for every number less than the number we are trying to check. This greatly adds to the computational complexity. This program runs very close to BigTheta(n^2). An easier way to run this would be a do-while loop or through the use of a break statement. Since you're using C, use an int as a bool marker (to prevent another lib import). Your inner loop would look like this:
int is_prime = 1;
for (d = 2; d < p; d++)
{
if (p % d == 0)
{
is_prime = 0
break;
}
}
if (is_prime)
printf("%d ", p);
There are additional methods of reducing the complexity, but those rely on better algorithm design moreso than more efficient code. For a beginner's project, think about why the current version of your code is inefficient (even if it was working properly). A lot of it comes with experience, but you shouldn't neglect individual code- and algorithm review.

You need to put your printf lines outside your inner loop.
Like this:
int main (void)
{
int p, d;
_Bool isprime;
for (p=2;p<=50;++p){
isprime = 1;
for (d=2;d<p;++d){
if (p%d == 0) {
isprime = 0;
break;
}
}
if (isprime)
printf("%i ", p);
}
return 0;
}

You have to use break statement. Without break, every time the calculation is performed, thus so many repetition in your original code. But even with break statement your code will generate many non desirable numbers/output instead of just generating prime numbers. So i have written following code for you. It will generate prime numbers as per your question.
Use the following code for generating prime numbers upto 50.
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int prime,i,k,j,max;
printf("2\n");
printf("3");
for(i=4; i<max; i++)
{
if(i%2!=0 && i%3!=0 && i%5!=0 && i%7!=0)
{
prime=i;
printf("\n%d",prime);
k++;
}
}
}

Related

Insertion sort algorithm, weird behaviour

I am learning C programming and I'm currently on a classic one, the insertion sort algorithm.
For contextualization, I have a set of 3 arrays to test on :
the first one which is disordered
the second one is in a descending order
and the last one is is the ordered one but with a swap between 2 elements.
Here is my code :
int insertionSort(int* tab, int n){
int i;
for (i=1; i<n; i++){
int j = i;
while(tab[j] < tab[j-1]) {
swap(&tab[j-1], &tab[j]);
j-=1;
}
}
affiche(tab, n);
return 0;
}
For the 2 last arrays, it works fine.
But for the first one I got :
6 6 7 8 10 32521 14 15 17 19 20 21 23 25 26 28 28 28 32 32 34 35 38 38 39 43 44 46 48 49 50 58 59 62 64 65 69 71 75 79 79 79 81 84 86 89 92 93 97 99
instead of
3 6 6 7 8 10 14 15 17 19 20 21 23 25 26 28 28 28 32 32 34 35 38 38 39 43 44 46 48 49 50 58 59 62 64 65 69 71 75 79 79 79 81 84 86 89 92 93 97 99
As you can see, the algorithm works fine for a big part of the array, but for the sixth minimal values, I have random values (sometimes there are 92,93,97... for the first ones).
I don't have any core dump, which means that I am in the array's space in memory, but some values like 32521 let me think that my index j goes too far in memory.
Frankly, I don't see where the problem is.
Look at this loop
while(tab[j] < tab[j-1]) {
swap(&tab[j-1], &tab[j]);
j-=1;
}
j can run happily all over the place. There needs to be something that detects that j isnt < 0 (actually < 1 since you access 'tab[j-1]')
maybe
while((j >= 1) && (tab[j] < tab[j-1]) ) {
swap(&tab[j-1], &tab[j]);
j-=1;
}

Output in read file and sort integers leaves a white space I can't find

My code takes in a text document argument and sorts the integers but when I run testing, it fails a simple white space at the end instead of a \n but I figure out how to stop the final number in the array with a new line instead of a space. Here is the code:
/* display values */
for (i = 0; i < count; i++ ) {
printf ("%ld ", sorted[i]);
}
Here is the test result and the issue:
Program Output
1: 1 2 3 4 5 5 7 8 9 9 9 10 10 11 11 12 14 17 18 20 20 20 24 24 25 25 26 26 27 27 28 28 29 30 30 30 30 31 33 35 35 36 38 40 40 41 42 42 42 47 47 47 48 48 48 48 50 50 51 52 52 52 54 54 57 57 57 57 57 60 61 61 62 62 62 63 64 66 66 66 67 67 69 70 72 72 73 73 75 77 80 82 83 83 83 84 85 86 87 88 88 88 89 91 92 93 94 94 96 97 97 99 [blank space]
Expected Program Output
1: 1 2 3 4 5 5 7 8 9 9 9 10 10 11 11 12 14 17 18 20 20 20 24 24 25 25 26 26 27 27 28 28 29 30 30 30 30 31 33 35 35 36 38 40 40 41 42 42 42 47 47 47 48 48 48 48 50 50 51 52 52 52 54 54 57 57 57 57 57 60 61 61 62 62 62 63 64 66 66 66 67 67 69 70 72 72 73 73 75 77 80 82 83 83 83 84 85 86 87 88 88 88 89 91 92 93 94 94 96 97 97 99
2: [new line]
I tried putting in a \n in printf ("%ld ", sorted[i]); after sorted[i] but it needs to go at the close of the array and I'm not certain how (or where) to add it with cause more issues.
/* display values */
for (i = 0; i < count; i++ ) {
printf ("%ld ", sorted[i]);
}
This outputs a space after each number. If that's not what you want, don't do it. Maybe you want this:
/* display values */
if (count > 0)
printf ("%ld", sorted[0]);
for (i = 1; i < count; i++ ) {
printf (" %ld", sorted[i]); // space before every number but first
}
If one doesn't want to duplicate code.
#include <stdio.h>
int main(void) {
const size_t count = 100;
size_t i;
/* display values */
for (i = 0; i < count; i++ ) {
printf ("%s%ld", i ? " " : "", i + 1 /*sorted[i]*/ );
}
fputc('\n', stdout);
return 0;
}
I expect it to be slower, but I think the intent of the code is clearer.

Illegal instruction (core dumped) error: scanf in a while loop until EOF

So I wrote a function in C which gets input until EOF
while (scanf(" %c", &input) != EOF) {
// do stuff
}
I tried to use the following test:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
10 20 30 40 50 _66_ 15 66bb
As an input to the program. It actually runs the program but at the end it finishes with the following error: Illegal instruction (core dumped).
Other tests work fine, and after a quick check I found out that the problem begins after the last 50 (if I use only the numbers until 50 - it works fine). How to solve this problem?

Printing from 1 to 100 in columns

Code:
for(int i = 1; i <= 100; i++){
if(i % 10 == 1)
printf("\n%d", i);
else printf("%4d",i);
}
Results:
(blank line)
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
How can I remove the first blank line without doing something like:
for(int i = 1; i <= 100; i++){
if(i == 1 || i % 10 == 1)
printf("\n%d", i);
else printf("%4d",i);
}
And how can I 'indent' the columns? As the last column isn't properly arranged, and I have no idea how to fix it using printf's.
At last, sorry for wrinting '(blank line)' as I don't know how to make a blank line, and thanks for the help.
Rather than printing a newline at the start of a line, print it at the end instead:
for (int i = 1; i <= 100; i++){
printf("%4d",i);
if (i % 10 == 0)
printf("\n");
}
This prints each number in a 4 character field, then prints a newline if the last number is divisible by 10.
Output:
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100
The style is strange, a newline doesn't belong at the start of a string literal. A printf call should print the line and then output a newline if necessary:
"\nBad style"
"Good style\n"
To print the values correctly, change the logic. Always print the values of i, and then check if i is divisible by 10, and print the newline if it is.
for(int i = 1; i <= 100; i++)
printf("%*d%c", (i % 10 == 1)? 0 : (i == 2) ? 4 : 3, i, (i % 10) ? ' ' : '\n');
I have always done something like this:
#include <stdio.h>
int main (void) {
for (int i = 0; i < 100; i++) {
if (i && i % 10 == 0) putchar ('\n');
printf ("%4d", i + 1);
}
putchar ('\n');
return 0;
}
You can also you separate format strings to accomplish the same thing:
char *fmt = "%4d",
*fmtn = "%4d\n";
for (int i = 0; i < 100; i++)
printf ((i+1) % 10 == 0 ? fmtn : fmt, i + 1);
putchar ('\n');
(note: in both cases the loop is indexed from 0 to accommodate indexing arrays)
Example Use/Output
$ ./bin/arraycols
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68 69 70
71 72 73 74 75 76 77 78 79 80
81 82 83 84 85 86 87 88 89 90
91 92 93 94 95 96 97 98 99 100

Runtime error in codechef practice questions

I'm getting "sigsegv" , a runtime error from the following code when i try to run it on codechef while the code works fine on my computer with various test inputs.I've also kept in mind the constraints given in the problem but I'm still unable to debug it. The question is not from any contest but a practice problem . Please point out any mistake you can find .
Actual codechef question
#include<stdio.h>
int cash[101][101]={0};
int rec[101][2];
int ri=0;
int sumx(int mat[101][101],int i,int j,int lines)
{
int n=0,a=0,b=0;
if(cash[i][j]!=0)
{
return cash[i][j];
}
else if(i==lines-2)
{
n=(mat[i+1][j]>mat[i+1][j+1])?mat[i+1][j]:mat[i+1][j+1];
cash[i][j]=n+mat[i][j];
rec[ri][0]=i;
rec[ri++][1]=j;
return n+mat[i][j];
}
else
{
a=sumx(mat,i+1,j,lines);
b=sumx(mat,i+1,j+1,lines);
n=(a>b)?a:b;
cash[i][j]=n+mat[i][j];
rec[ri][0]=i;
rec[ri++][1]=j;
return n+mat[i][j];
}
}
int main()
{
int i=0,k=0;
int lines=0,n=0;
int r=0;
int tc=0;
int mat[101][101];
scanf("%d",&tc);
while(tc--)
{
scanf("%d",&lines);
i=0;
k=0;
while(i<lines)
{
while(k<=i)
{
scanf("%d",&mat[i][k]);
k++;
}
k=0;
i++;
}
if(lines==1)
{
r=mat[0][0];
}
else
{
r=sumx(mat,0,0,lines);
}
i=0;
while(i<ri)
{
cash[(rec[i][0])][(rec[i][1])]=0;
rec[i][0]=0;
rec[i][1]=0;
i++;
}
ri=0;
printf("%d\n",r);
}
return 0;
}
The error is with lines
while(i<ri)
{
cash[(rec[i][0])][(rec[i][1])]=0;
rec[i][0]=0;
rec[i][1]=0;
i++;
}
the values of rec[i][0] rec[i][1] can be undefined in some cases ie they may return garbage values
You can Use memset instead to change the values to 0
memset(rec,0,sizeof(rec));
memset(cash,0,sizeof(cash));
I ran your solution , there's a bug in your algorithm implementation try finding it yourself
I can provide you a test case(using a testcase generator) for which it fails
21
79
89 28
14 6 63
96 58 67 48
80 8 22 27 8
24 21 23 96 97 72
38 90 95 83 57 60 94
13 96 9 24 65 27 67 40
26 20 58 42 29 8 52 49 37
80 65 65 34 79 10 89 11 20 84
57 59 72 79 51 67 84 70 43 62 96
16 4 18 9 5 40 34 2 15 4 28 50
29 1 60 39 28 92 38 65 95 57 10 71 37
25 78 96 43 17 51 88 19 0 30 20 80 39 35
55 41 63 76 4 20 97 72 43 93 76 11 82 33 25
61 85 41 77 42 90 20 5 69 51 4 54 41 18 83 72
12 56 21 82 7 1 84 26 47 26 22 52 84 39 75 70 89
12 39 83 92 49 20 35 20 31 96 66 75 48 79 13 51 49 50
42 81 0 58 70 40 16 83 27 34 79 64 14 26 19 22 38 55 93
64 81 26 29 47 22 73 61 3 2 61 99 18 43 33 10 13 46 24 53
5 56 0 0 3 0 71 12 82 34 17 11 14 51 1 82 73 53 85 75 89
correct answer is 1431 while your code returns 1299
#Randomizer : The code runs fine with the output as 1431 , not 1299 . Anyways , as you suggested about the garbage being generated from rec[i][0] rec[i][1], It never appeared to me that rec[i][0] rec[i][1] could be generating garbage as I only accessed the used up cells . However , memset eliminated the need of rec , so cash was easily reset to zero . All i did was remove the rec matrix and reset cash using memset and the code ran fine on codechef. I couldn't figure out how it could be generating garbage , still , its accepted on codechef since I removed rec part . Thank you for the help.

Resources