I have to write a program to open a file that contains 3 columns, each row represents data for a baseball player. the first columns represents the players number, second is times at bat, lastly the third is average hits. I have to sort the players in descending order of average hits. I am having a problem, it orders them in descending order of number times at bat. also the first 3 numbers are not printing out correctly.
here are the first 3 players data
3 5 .400
5 1 .000
9 30 .167
here is my code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float BattingA[13], At_Bat[13];
int Player_ID[13];
void Sort_Arrays(int ID[], float at_bat[], float average[]);
int main()
{
int ID[13];
float at_bat[13], average[13];
FILE *readfile;
int i;
if ((readfile = fopen("cubs-batting-ws-ab-avg.txt", "r")) == NULL)
{
printf("The file failed to open\n");
}
for (i = 0; i < 13; i++)
{
fscanf(readfile, "%d %f %f", ID + i, at_bat + i, average + i);
Sort_Arrays(ID, at_bat, average);
}
printf("numbers\n");
for (i = 0; i < 13; i++)
{
printf("%d %.0f %.3f \n", ID[i], at_bat[i], average[i]);
}
if (fclose(readfile) == EOF)//close the file.
{
printf("The file failed to close.\n");
}
return 0;
}
void Sort_Arrays(int ID[], float BattingA[], float AtBat[])
{
int x, y = 13, z;
float New, NewID, NewAtBat;
for (x = 0; x < y; x++)
{
for (z = x + 1; z < y; z++)
{
if (BattingA[x] < BattingA[z])
{
NewID = ID[x];
NewAtBat = AtBat[x];
New = BattingA[x];
ID[x] = ID[z];
AtBat[x] = AtBat[z];
BattingA[x] = BattingA[z];
ID[z] = NewID;
AtBat[z] = NewAtBat;
BattingA[z] = New;
}
}
}
}
anything you could do to help i would really appreciate it.
thank you all.
The arguments are being passed to the Sort_Arrays function in the wrong order. at_bat is being passed in as the 2nd argument. As Sort_Arrays is written to sort according to the 2nd argument, your arrays are being sorted according to at_bat.
Related
I am writing a program that will take any number of integers. The program will end when the terminal 0 has been entered. It will then output the number closest to 10 (except for the terminal character). If there are several numbers closest to 10 then it should output the last number entered.
My current code does read the numbers from the input stream, but I don't know how to implement the logic so that the program will give me the number that is closest to 10.
I know, that I need to keep track of the minimum somehow in order to update the final result.
#include <stdio.h>
int main() {
int n = 1;
int number = 1;
int numberArray[n];
int resultArray[n];
int min;
int absMin;
int result;
int finalResult;
while (number != 0) {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
for (int i = 0; i < n; i++) {
min = 10 - numberArray[i];
if (min < 0) {
absMin = -min;
}
else {
absMin = min;
}
resultArray[i] = absMin;
result = resultArray[0];
if (resultArray[i] < result) {
finalResult = resultArray[i];
}
}
printf("%d\n", finalResult);
return 0;
}
here's a simple code I wrote
One thing I must say is you can't simply declare an array with unknown size and that's what you have done. Even if the no. of elements can vary, you either take input the number of elements from the user OR (like below) create an array of 100 elements or something else according to your need.
#include <stdio.h>
#define _CRT_NO_WARNINGS
int main() {
int n = 0;
int number = 1;
int numberArray[100];
int resultArray[100];
int minNumber;
int *min;
do {
scanf("%d", &number);
numberArray[n] = number;
n++;
}
while (number != 0);
resultArray[0] = 0;
min = &resultArray[0];
minNumber = numberArray[0];
for (int i = 0; i < n-1; i++) {
if(numberArray[i]>=10){
resultArray[i] = numberArray[i] - 10;
}
if(numberArray[i]<10){
resultArray[i] = 10 - numberArray[i];
}
if(resultArray[i] <= *min){
min = &resultArray[i];
minNumber = numberArray[i];
}
}
printf("\n%d",minNumber);
return 0;
}
I have improved your script and fixed a few issues:
#include <stdio.h>
#include <math.h>
#include <limits.h>
int main()
{
int n;
int number;
int numberArray[n];
while (scanf("%d", &number) && number != 0) {
numberArray[n++] = number;
}
int currentNumber;
int distance;
int result;
int resultIndex;
int min = INT_MAX; // +2147483647
for (int i = 0; i < n; i++) {
currentNumber = numberArray[i];
distance = fabs(10 - currentNumber);
printf("i: %d, number: %d, distance: %d\n", i, currentNumber, distance);
// the operator: '<=' will make sure that it will update even if we already have 10 as result
if (distance <= min) {
min = distance;
result = currentNumber;
resultIndex = i;
}
}
printf("The number that is closest to 10 is: %d. It is the digit nr: %d digit read from the input stream.\n", result, resultIndex + 1);
return 0;
}
Reading from the input stream:
We can use scanf inside the while loop to make it more compact. Also, it will loop one time fewer because we don't start with number = 1 which is just a placeholder - this is not the input - we don't want to loop over that step.
I used the shorthand notation n++ it is the post-increment-operator. The operator will increase the variable by one, once the statement is executed (numberArray entry will be set to number, n will be increased afterwards). It does the same, in this context, as writing n++ on a new line.
Variables:
We don't need that many. The interesting numbers are the result and the current minimum. Of course, we need an array with the inputs as well. That is pretty much all we need - the rest are just helper variables.
Iteration over the input stream:
To get the result, we can calculate the absolute distance from 10 for each entry. We then check if the distance is less than the current minimum. If it is smaller (closer to 10), then we will update the minimum, the distance will be the new minimum and I have added the resultIndex as well (to see which input is the best). The operator <= will make sure to pick the latter one if we have more than one number that has the same distance.
I have started with the minimum at the upper bound of the integer range. So this is the furthest the number can be away from the result (we only look at the absolute number value anyway so signed number don't matter).
That's pretty much it.
I have been solving a problem of the dynamic array on the hackerrank. The problem is of organizing books on shelves of a library. Here is the link to the question.
I have solved the problem on my computer and compile it successfully but when I try to compile it on the hackerrank platform it gives:
double free or corruption (out) error.
After compiling it on my computer when I run the program and pass the value it gives a different output for the same conditions, for example:-
here is code:-
#include <stdio.h>
#include <stdlib.h>
/*
* This stores the total number of books in each shelf.
*/
int* total_number_of_books;
/*
* This stores the total number of pages in each book of each shelf.
* The rows represent the shelves and the columns represent the books.
*/
int** total_number_of_pages;
int main()
{
int i, count = 0,len,*ptr;
int total_number_of_shelves;
scanf("%d", &total_number_of_shelves);
int total_number_of_queries;
scanf("%d", &total_number_of_queries);
len = sizeof(int *) * total_number_of_shelves + sizeof(int) * 1100 * total_number_of_shelves;
total_number_of_books = (int*)calloc(total_number_of_shelves , 4);
total_number_of_pages = (int**)malloc(len);
ptr = (int *)(total_number_of_pages+total_number_of_shelves);
for(i = 0; i < total_number_of_shelves; i++)
total_number_of_pages[i] = (ptr + 1100 * i);
while (total_number_of_queries--) {
int type_of_query;
scanf("%d", &type_of_query);
if (type_of_query == 1) {
int x, y;
scanf("%d %d", &x, &y);
total_number_of_books[x]+=1;
for (i = 0; i<1100; i++)
{
if(total_number_of_pages[x][i] != 0)
{
count++;
}
}
if(count == 1100)
{
printf("\nShelve is full\n");
}
else
{
for(i = 0; i < count; i++)
{
total_number_of_pages[x][count-i] = total_number_of_pages[x][count-1-i];
}
total_number_of_pages[x][count-i-1] = y;
}
} else if (type_of_query == 2) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", *(*(total_number_of_pages + x) + y));
} else {
int x;
scanf("%d", &x);
printf("%d\n", *(total_number_of_books + x));
}
}
if (total_number_of_books) {
free(total_number_of_books);
}
for (int i = 0; i < total_number_of_shelves; i++) {
if (*(total_number_of_pages + i)) {
free(*(total_number_of_pages + i));
}
}
if (total_number_of_pages) {
free(total_number_of_pages);
}
return 0;
}
Sample Input
5
5
1 0 15
1 0 20
1 2 78
2 2 0
3 0
Sample Output
78
2
In this program when I input 2 2 0 it should give result as 78 but it gives 0 as output. The problem becomes much confusing when I add a small code in the program at the given section i.e.
Code :- printf("\n%d\n",total_number_of_pages[x][count-i-1]); added in below given portition of code:
else
{
for(i = 0; i < count; i++)
{
total_number_of_pages[x][count-i] = total_number_of_pages[x][count-1-i];
}
total_number_of_pages[x][count-i-1] = y;
printf("\n%d\n",total_number_of_pages[x][count-i-1]); //this code is added extra to check the inputed value
}
after doing this it will print the value immedietly from the array after entering the value in the array for given position.
Above formated code prints the correct value of the given position of the array but when I try to print it using this portion of code it only returns 0 as the output.
Code:-
else if (type_of_query == 2) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", *(*(total_number_of_pages + x) + y));
If i try to give constant value in place of x and y in both code's then also the result will be same i.e correct value at first portition of code and 0 at above code even though there is no change in the logic of printing the value.
Please help me to solve these two problems:-
1. Wrong output value.
2. Compilation error double free or corruption (out) at hackerrank platform for same code.
One obvious error is here:
total_number_of_pages = (int**)malloc(len);
...
for (int i = 0; i < total_number_of_shelves; i++) {
if (*(total_number_of_pages + i)) {
free(*(total_number_of_pages + i));
}
}
You allocate one memory block and then you try to free pointers in the middle of the block. This will cause problems. You only need to free once for one allocation. So:
free(total_number_of_pages)
This my first post on here. I'd like to ask about a problem that I am trying to do for homework.
I'm supposed to be constructing a for loop for the "first 5 factorials" and display results as a table. I followed an example in the book, and I have my for loop and my operations set up, but I don't know what to do to produce the loop in the table. Here is my program:
#include <stdio.h>
int main(void) {
//Problem: Display a range for a table from n and n^2, for integers ranging from 1-10.
int n, factorialnumber, i;
printf("TABLE OF FACTORIALS\n");
printf("n n!\n");
printf("--- -----\n");
for (n = 1; n <= 10; n++) {
factorialnumber = factorialnumber * n;
printf("\n %i = %i", factorialnumber, n);
}
return 0;
}
I know the printf here is wrong. What would I type?
BTW, I'm using codeblocks.
The problem is that you didn't initialize the variables (e.g. factorialnumber). If it has an initial value of 6984857 let's say, the whole algorithm would be messed up.
Try this :
#include <stdio.h>
int main(void) {
//Problem: Display a range for a table from n and n^2, for integers ranging from 1-10.
int i, factorialnumber = 1;
int n = 10; // Max number to go through
printf("TABLE OF FACTORIALS\n");
printf("i i!\n");
printf("--- -----\n");
for (i = 1; i <= n; i++) {
factorialnumber *= i;
printf("%d! = %d\n", i, factorialnumber);
}
return 0;
}
I have a C binary file with 5123 values in the form of a 3-dimensional cube. I need to access the position in the cube with the highest value, which is the density. Once I have the position of the highest value, I need to create a smaller 3D cube about this position with values that are obviously smaller than 512 (the dimension of the cube). start represents the position at one corner of the smaller cube. p is the binary file obviously.
fseek(p,0,SEEK_END);
lSize = ftell(p);
rewind(p);
dim = pow(lSize/sizeof(float),1.0/3.0);
printf("File size: %lu bytes, Grid size: %d \n", lSize,(int)dim);
max = 0;
counter = 0;
index = 0;
while(fread(&density,sizeof(float),1,p),!feof(p) && !ferror(p)) {
if(density > max) max = density,index = counter;
counter += 1;
}
sub = 256;
start = index - (pow(dim,2)+dim+1)*(sub/2-1);
printf("3d coordinates of highest density: %lu,%lu,%lu, Dimension of cube: %d\n",index % 512;(index / 512) % 512;index / (512 * 512),(int)dim);
printf("The maximum density is: %e with index: %lu \n", max,index);
rewind(p);
fseek(p,start*sizeof(float),SEEK_SET);
fseek(q,start*sizeof(float),SEEK_SET);
fseek(r,start*sizeof(float),SEEK_SET);
fseek(s,start*sizeof(float),SEEK_SET);
fseek(t,start*sizeof(float),SEEK_SET);
u = fopen("results_dens.dat", "w");
if (u == NULL) { printf("Unable to open output results file!"); exit(1); }
for (ibox=0;ibox<nbox;ibox++){
for (k=0;k<nz[ibox];k++){
fseek(p,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(q,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(r,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(s,(start+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(t,(start+k*dim*dim)*sizeof(float),SEEK_SET);
for (j=0;j<ny[ibox];j++){
fseek(p,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(q,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(r,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(s,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
fseek(t,(start+j*dim+k*dim*dim)*sizeof(float),SEEK_SET);
for (i=0;i<nx[ibox];i++){
I am aware that the above code runs without any errors. However, a lot rides on the value of index above. I am unsure of how positions are defined in C. I am aware that these are memory locations but by doing some rough calculations, the value of index that I derive seems to be close to the edge of the box and not the centre.
5123 = 134217728.
The value of index is 66978048, 130816 positions from the middle position value of 67108864. But, 130816 is approximately 512*256 meaning that if the middle position of the grid is at the edge of the box, then so is index above.
Perhaps this will help. First, I created a test file with the following program:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int makeCube(const char *fn, int dim)
{
FILE *p;
const int center = dim/2;
p = fopen(fn,"w");
for (int i=0; i < dim; ++i)
for (int j=0; j < dim; ++j)
for (int k=0; k < dim; ++k) {
float f = dim - sqrtf(pow(i-center,2)+
pow(j-center,2)+pow(k-center,2));
fwrite(&f, sizeof(float), 1, p);
}
fclose(p);
return 0;
}
int main()
{
const int dim = 512;
makeCube("cube.bin", dim);
return 0;
}
Next I rewrote your code to have correct syntax and to print some diagnostics which seemed useful:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int subCube(FILE *p, int dim)
{
float density;
float max = 0;
long index = 0;
long counter;
for (counter=0; fread(&density,sizeof(float),1,p); ++counter) {
if(density > max) {
max = density;
index = counter;
}
}
printf("The maximum density is: %e with index: %lu \n", max,index);
int i = index/dim/dim;
int j = (index - (i*dim*dim))/dim;
int k = (index - ((i*dim)+j)*dim);
printf("This corresponds to coordinates (%d,%d,%d)\n", i,j,k);
}
int main()
{
const int dim = 512;
FILE *p = fopen("cube.bin","r");
subCube(p, dim);
fclose(p);
return 0;
}
When I run that program, I get the following output:
The maximum density is: 5.120000e+02 with index: 67240192
This corresponds to coordinates (256,256,256)
Since the test data was basically a sphere with greatest density at the middle, this is exactly as expected.
Note that I have played fast and loose with error handling (there isn't any!) but it's omitted for clarity and not because you should actually omit it in a real program.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (void) {
int i,j,z,w,c; /* counter*/
int ticket[6],n[6];
int a; /*numbers of one ticket*/
int x; /* Random numbers of tickets*/
int num; /*Quantity of tickets*/
int loser = 0; /*initialize the number of known-tickets*/
int threeknown = 0;
int fourknown = 0;
int fiveknown = 0;
int winner = 0;
srand (time(NULL));
printf ("Please enter the lucky ticket numbers between 0 and 50\n");
for (i=0;i<6;i++) { /* loop for entering numbers of ticket from keyboard*/
scanf ( "%d",&a);
if (a<50 && a>0){
ticket[i] = a;
}
else {
printf ("\a ERROR: Please enter number between 0 and 50\n");
i--; /* enter again */
}
}
printf ("Lucky ticket is:\n");
for (i=0;i<6;i++) {
printf ("%3d",ticket[i]);
}
printf ("\n");
printf ("Please enter the quantity of tickets\n\a");
scanf ("%d",&num);
for (z=0;z<num;z++) { /* For each ticket */
for (j=1;j<=6;j++) {
x = 1 + rand()%49;
n[j] = x;
printf ("%3d",n[j]);
}
printf("\n\n");
}
for (z=0;z<num;z++){ /*counter for each ticket control */
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3] && ticket[4]==n[4] && ticket[5]==n[5]) {
winner += 1;
}
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3] && ticket[4]==n[4]) {
fiveknown += 1;
}
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3]) {
fourknown += 1;
}
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2]) {
threeknown += 1;
}
else {
loser += 1;
}
}
printf ("Number of winners : %d\n",winner);
printf ("Number of five-knowns : %d\n",fiveknown);
printf ("Number of four-knowns : %d\n",fourknown);
printf ("Number of three-knowns : %d\n",threeknown);
printf ("Number of losers : %d\n",loser);
system ("PAUSE");
return 0;
}
I have project about C coding Bingo Program. I need to maintain a winner ticket from keyboard between 0 and 50 (12 34 23 11 47 4) and then I need to generate tickets randomly. In these tickets none of them have the same number and the sorting is not important. For example ( 23 12 10 4 9 46 ). My question is to how to have these kind of tickets ? I don't want to have this kind of tickets ( 12 43 20 12 9 4 )
Build an array of the fifty acceptable values, choose one, and then remove it from the array.
Since the order in the array is not important, you can remove it at little cost by overwriting it with the last value and decreasing the "array count" variable.
void RemoveFromArray(int* arr, size_t *pNumberOfElements, size_t indexToRemove)
{
//Note: I'm not putting the error/bounds checking because it's not what the question is about.
size_t indexLast = *pNumberOfElements - 1;
arr[indexToRemove] = arr[indexLast];
(*pNumberOfElements)--;
}
void ChooseRandom6of50(int* random6ints)
{
int arr[50];
size_t nElements = 50;
{
size_t i;
for(i=0 ; i<50 ; i++)
arr[i] = (int)(i+1); //Fill with values 1 to 50
}
{
size_t iDest;
for(iDest=0 ; iDest<6 ; iDest++)
{
int rnd = rand() % nElements; //The real code should use the more elaborate random formula
size_t randIndex = rnd;
random6ints[iDest] = arr[randIndex];
RemoveFromArray(arr, &nElements, randIndex);
}
}
}
For a small number of tickets picked, the easiest way is to draw tickets randomly as you did already, but draw again if the ticket is already in the lot of drawn ticktes until you have a new ticket:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX
int contains(int ticket[], int n, int which)
{
while (n-- > 0) {
if (ticket[n] == which) return 1;
}
return 0;
}
void draw(int ticket[], int n, int m)
{
int i, t;
if (n > m) return;
for (i = 0; i < n; i++) {
do {
t = rand() % m;
} while (contains(ticket, i, t));
ticket[i] = t;
}
}
int main (void)
{
int ticket[6];
int i;
draw(ticket, 6, 50);
for (i = 0; i < 6; i++) printf("%4d", ticket[i]);
printf("\n");
return 0;
}
Note that the draw function does not do anything if the number of tickets to draw, n, is bigger than the tickets available, m, because that would lead to an infinite loop. If n == m the draw is like shuffling, albeit in a very inefficient way. (The draw function should probably return an error code or abort the program in that case, but in oder to keep things simple, I've left that out.)
The contains function should also come in handy if you want to compare the user's tickets with the draw. (Also, it would look more like programming if you could turn your variable threeknown, fiveknown and so on into an array hits[7].)