histogram went in to infinite loop - c

Hi I have this code here
int calMode(RECORD list[], int count)
{
int tempMode = 1;
int i = 1, j, k;
int current = 0;
while ( i <= count)
{
k = 1;
if (list[current].score == list[current + i].score)
{
k++;
i++;
}
printf("%d:", list[current].score);
for(j = 0; j <= k ; j++)
{
printf("*");
}
printf("\n");
current = current + k;
i++;
}
return tempMode;
}
I thought the logic of the code is ok, why is it going into an infinite loop ?
can anyone suggest a way to fix this code? and the list of data is assume to be sorted before going into the function calMode, I think there is a problem at the for loop
I edited the code know my out put is
60
66
71
71
72
75
79
82
82
82
91
size is: 12
73.50
60:**
66:*
71:*
71:*
72:*
75:*
79:*
82:*
82:*
82:*
91:*
The output is wrong but it is no longer in infinite loop

if (list[current].score == list[i].score)
{
k++;
i++;
}
If this test is wrong, i will never be incremented and here is the infinite loop.

FIX E.g.
int calMode(RECORD list[], int count){
int tempMode = 1;
int i, k;
int current = 0;
while (current < count){
printf("%d:", list[current].score);
for(k=0; (i=current + k) < count ; ++k){
if(list[current].score == list[i].score)
printf("*");
else
break;
}
printf("\n");
current = current + k;
}
return tempMode;
}

According to your code, if the scores of 0 th elemennt and 1st element are not equal, it will end up in infinite loop. I think some increment condition should be outside if statement too. [I dont know your logic, this is just a guess]

Related

How can I make my Code work on Larger Inputs

I'm trying to solve the hacker rank question "Small triangle, Large triangle"
I have to arrange triangle by increasing order of area
the code I wrote is working fine on smaller input given by me but fails on the larger inputs, after taking inputs I just get terminated
eg,
working on input
3
7 24 25
5 12 13
3 4 5
not working when
10
67 67 19
3 57 55
33 33 49
61 58 59
23 43 35
48 42 45
23 12 27
41 34 22
26 49 35
63 46 45
unable to understand why!! Thank YOU!! in advance
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct triangle
{
int a;
int b;
int c;
};
typedef struct triangle triangle;
void sort_by_area(triangle *tr, int n)
{
int *p = (int*)malloc(n * sizeof(int));
int *middle = (int*)malloc((3*n)*sizeof(int));
// doing sum of side of triangle
for (int i = 0; i < n; i++)
{
p[i] = tr[i].a + tr[i].b + tr[i].c;
}
// arranging sum in increasing order
// as more the sum of a+b+c more its area in herons formula
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (p[i] < p[j])
{
int temp;
temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
int num = 0;
// storing sides in increasing order in middle
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (p[i] == tr[j].a + tr[j].b + tr[j].c)
{
middle[num] = tr[j].a;
num++;
middle[num] = tr[j].b;
num++;
middle[num] = tr[j].c;
num++;
}
}
}
num=0;
// copying increassed order in tr poiinter in question
for (int i = 0; i < n; i++)
{
tr[i].a = middle[num];
num++;
tr[i].b = middle[num];
num++;
tr[i].c = middle[num];
num++;
}
}
int main()
{
int n;
scanf("%d", &n);
triangle *tr = malloc(n * sizeof(triangle));
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &tr[i].a, &tr[i].b, &tr[i].c);
}
sort_by_area(tr, n);
for (int i = 0; i < n; i++) {
printf("%d %d %d\n", tr[i].a, tr[i].b, tr[i].c);
}
return 0;
}
It's kind of strange that your function is called sort_by_area but it doesn't seem to calculate any area. Instead it seems to calculate the perimeter of the triangles.
Anyway... there is a bug here. (note: There may be other bugs but to start with you need to fix this)
int *middle = (int*)malloc((3*n)*sizeof(int));
...
...
int num = 0;
// storing sides in increasing order in middle
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (p[i] == tr[j].a + tr[j].b + tr[j].c)
{
middle[num] = tr[j].a;
num++;
middle[num] = tr[j].b;
num++;
middle[num] = tr[j].c;
num++;
}
}
}
You have two nested loops going from 0 to n. When the if statement is true, you increment num 3 times.
So in case p[i] == tr[j].a + tr[j].b + tr[j].c is always true (which is possible), you end up with num being equal to 3*n*n.
And you use num as index into middle but middle is only allocated to hold 3*n integers.
So you are writing outside the allocated area. That's undefined behavior.
BTW
When sorting arrays in C you should nearly always use qsort

Why does while loop sometimes exit before exit condition is met?

I need to create a string of variable length composed of random characters, so I built a function that does just that, however, after executing it a few times I noticed that the while loop stops executing even though the condition is still not met at first I had (j < taille) but then I changed it to (j <= taille ) but I still have the same problem , sometimes it doesn't execute normally
here's my code:
void gener_observation(char num[b])
{
int taille,i,j;
srand(time(NULL));
taille = (rand()%(b-40)) + 1;
j=0;
i=0;
while(j <= taille)
{
i = ((rand()%26) + 65 );
num[j] = i;
j++;
}
}
Turn your code into this:
void gener_observation(char num[b])
{
int taille,i,j;
srand(time(NULL));
taille = (rand()%(b-40)) + 1;
j=0;
i=0;
printf("The value of taille equals [%d]", taille);
while(j <= taille)
{
printf("Currently, j equals [%d]", j);
i = ((rand()%26) + 65 );
num[j] = i;
j++;
}
printf("Finished");
}
... and run your code again. As your code contains a random number, it might be different for all of us, but using the printed results, you might find out the problem you're having.

How to stop the loop after printing one?

So here is the problem: Write a program that accept an integer n, print out the largest number but smaller or equal n that is the product of two consecutive even number. Example: Input: 12, Output: 8 ( 2x4 )
Here is my code :
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d ", i);
break;
}
}
}
return 0;
}
So if i input 20, it will print out 8 and 0 instead of 8, if i input 30, it will print out 24,8 and 0 instead of just 24. How do i make it stop after printing out the first number that appropriate ?
You need to stop an outer loop from processing, for example by using a boolean flag (meaning "solution found, we finish work") or a goto statement.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int solutionFound = 0;
for (int i = n; i >= 0; i--) {
// this could also be put into for's condition i.e. "i >= 0 && !solutionFound"
if (solutionFound) {
break;
}
for (int j = 0; j <= n; j = j + 2) {
if ( i == j * (j+2) ) {
printf("%d ", i);
solutionFound = 1;
break;
}
}
}
return 0;
}
EDIT: immediate return as noted in the comments is also a nice idea, if you don't need to do anything later.
Your problem is that you are nested - in a for loop which is inside another for loop - when you want to stop processing.
Some languages would let you code break 2; to indicate that you want to break out of 2 loops. Alas, C i snot such a language.
I would recommend that you code a function. That would serve a few porpoises: 1) your main should be "lean & mean" 2) as your programs get larger, you will learn the benefits of putting individual coding tasks into functions 3) you can use return; instead of break; and it will exit the function immediately.
Something like this:
#include <stdio.h>
void FindNeighbouringDivisors(int n)
{
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d times %d = %d", j, j + 2, i);
return;
}
}
}
printf("There are no two adjacent even numbers which can be multiplied to give %d", n);
}
int main()
{
int n;
scanf("%d", &n); /* could get from comamnd line */
FindNeighbouringDivisors(n);
return 0; /* should be EXIT_SUCCESS */
}
Btw, when you have a problem with your code, ask a question here. When you have it working, consider posting it at our code review site where more experienced programmers can give you advice on how to improve it. It's a great way to learn
Break only breaks you out of immediate loop, so either use flags or just use return to terminate the execution. Or you can even use following code:
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int j = 0; j <= n; j = j + 2)
{
if ( n < j * (j+2) )
{
printf("%d ", j*(j-2));
break;
}
}
return 0;
}

Prime number from 1 to 100 in C

I am writing a program to find prime numbers from 1 to 100. Please check if my code is correct or not. When I am running my code prime numbers are not getting printed. Please help.
#include <stdio.h>
#include <conio.h>
int main()
{
int i, j, flag, rem;
flag=0;
printf("2");
for(i=3; i<=100; i++)
{
for(j=2; j<=i; j++)
{
rem = i%j;
if(rem == 0)
{
flag=1;
break;
}
}
if(flag==0)
{
printf("%d", i);
}
}
getch();
return 0;
}
You have a couple of problems
First, the for(j=2;j<=i;j++) loop should be for(j=2;j<i;j++), as if j is equal to i, j % i == 0 will always be true
Second, your flag variable is not doing what you might think it is doing. As HolyBlackCat suggested this is a good opportunity to learn how to use a debugger to see what is happening. You need to reset the flag variable, because once you find a single composite number, your flag will not reset so all following numbers will be flagged as composite. Add:
for(i=3;i<=100;i++)
{
flag = 0;
for(j=2;j<=i;j++)
{
Change for (j = 2; j <= i; j++) to for (j = 2; j <= i/2; j++). You need to loop up to i/2.
int main()
{
int i, j, flag, rem;
printf("2\n");
for (i = 3; i <= 100; i++)
{
flag = 0;
for (j = 2; j <= i/2; j++)
{
if (i % j == 0)
{
flag = 1;
break;
}
}
if (flag == 0)
printf("%d\n", i);
}
getch();
return 0;
}
It is better to have a correct indentation for well-reading purposes. I added some comments in lines where you can optimize your code and I removed the unnecesary 'printf'. (\t is to write a tab space after what it is printed)
#include <stdio.h>
#include <conio.h>
int main()
{
int flag;
printf("Prime numbers: 2\t");
for(int i = 3; i <= 100; i++) // You can declare a temporal variable for the cycle
{
flag = 0; // reset the flag variable to zero when adding a new number
for(int j = 2; j < i; j++)
{
if(i%j == 0) // substitute the 'rem' variable for an operation
{
flag = 1;
break;
}
}
if(flag == 0)
{
printf("%d\t", i);
}
}
getch();
return 0;
}
The expected output will be:
Prime numbers: 2 3 5 7 11
13 17 19 23 29 31 37
41 43 47 53 59 61 67
71 73 79 83 89 97
You should reset flag at 0 each time you try a new number. Leaving the code like this, as soon as a number isn't prime, the code will never print again.
[...snip...]
for(i=3;i<=100;i++)
{
flag = 0;
for(j=2;j<=i;j++)
{
[...snip...]
The problem is flag is not set/reset correctly. and also there is a lot of scope for improvement in the code.
As you already print 2 as prime no so no need to check other even no as 2 is the only even no which is prime.
Instead of dividing form 2..n-1 we can check it for 2..n/2
Find the optimized code below:
// return 1 if no is prime else 0
int is_prime(int n)
{
for(int i = 3; i<= n/2; i+=2){
if (n%i == 0)
{
return 0;
}
}
return 1;
}
int main()
{
printf("2\n");
for(int i=3; i<=100; i+=2)
{
if (is_prime(i))
{
printf("%d\n", i);
}
}
return 0;
}

8 Queens puzzle with recursive deep search

I'm trying to solve the 8 queens puzzle problem in C. I'm having problems with the recursive search. The program is supposed to start at a given column:
execute(tabuleiro,8,0);
Where the 8 is the number of columns in the board, and 0 is the start column.
This works when I start at column 0. When I send any other column number to the recursive search, the program just counts to the last column. For example, if I choose to start the search from the number 5 column, the code search from the column 5 to 7, after this it should search from 0 to 4, but it doesn't do that.
If I do this:
execute(tabuleiro,8,3);
It fills in only the last 5 colummns, and does not return to column 0 to finish the solution:
Also, how can I select the initial position for the queen in this code? Like I said before, the column is assigned in the code, but I'm not sure how to pick the correct column.
The code has 3 functions: one is to display the board, a second to check if the move is legal (so one queen doesn't attack the other), and the last one to place one queen and recur for the remainder of the board.
#include <stdlib.h>
#include <windows.h>
int sol = 0;
void viewtab(int tab[][8], int N)
{
int i,j;
for( i = 0; i < N; i++)
{
for( j = 0; j < N; j++)
{
if(tab[i][j] == 1)
printf("R\t");
else
printf("-\t");
}
printf("\n\n");
}
printf("\n\n");
system("pause");
printf("\n");
}
int secury(int tab[][8], int N, int lin, int col)
{
// this function is to check if the move is secury
int i, j;
// attack in line
for(i = 0; i < N; i++)
{
if(tab[lin][i] == 1)
return 0;
}
//attack in colune
for(i = 0; i < N; i++)
{
if(tab[i][col] == 1)
return 0;
}
// attack in main diagonal
//
for(i = lin, j = col; i >= 0 && j >= 0; i--, j--)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j < N; i++, j++)
{
if(tab[i][j] == 1)
return 0;
}
// attack in main secondary
for(i = lin, j = col; i >= 0 && j < N; i--, j++)
{
if(tab[i][j] == 1)
return 0;
}
for(i = lin, j = col; i < N && j >= 0; i++, j--)
{
if(tab[i][j] == 1)
return 0;
}
// if arrive here the move is secury and return true
return 1;
}
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
for( i = 0; i < N; i++)
{
// check if is secury to put the queen at that colune
if(secury(tab, N, i, col))
{
// insert the queen (with 1)
tab[i][col] = 1;
// call recursive
execute(tab, N, col + 1);
// remove queen (backtracking)
tab[i][col] = 0;
}
}
}
int main()
{
int i, j, tabuleiro[8][8];
for (i = 0; i < 8; i = i + 1)
for (j = 0; j < 8; j = j + 1) tabuleiro[i][j] = 0;
execute(tabuleiro,8,0);
return 0;
}
The search always stops in the rightmost column because you specifically tell it to stop there:
void execute(int tab[][8], int N, int col)
{
int i;
if(col == N)
{
printf("Solution %d ::\n\n", sol + 1);
viewtab(tab, N);
sol++;
return;
}
Look at your termination condition: you check the current column against the highest column number, and stop there.
If you want to go back to column 0, you have to change your loop logic. For instance, let col reach N, at which point you reset it to 0, and let it continue until you hit the original value. Another way is to continue until the count of placed queens is N.
You choose the initial point in the same way: you pick the first one and make your recursive call. If that eventually results in a solution, you print it. If not, your top-most call continues to the next row (line) of the board and puts the first queen there.
This is already in your main logic. Just make sure that secury will return true when the board is empty, rather than false or throwing an error.
A. You can place the first Queen at (0,0).
B. And begin the search also from (0,0).
C. I do not see any need to start looking for some other index.
Successfully!!

Resources