Unknown test case error in C program - c

This a question I have to submit for an assignment, hence it has to be evaluated online. My program is running correctly for 6 out of 7 test cases. Only 3 test cases are provided and they are as shown:
Sports or Economy Car
Help Mr.Kamath to check whether his vehicle is an economy car or not. The program should display “There is a gas hog” if the mileage is less than or equal to 15 Km and the program should display “It is an economy car” if the mileage is not less than 30 Km. Otherwise display "Fuel Economy". Write a C program to get the values of a Car variables from the user. Create a structure called Car. Order of the input values entered should be according to the structure variables
struct Car{
float startKm;
float endKm;
float litres;
};
Test Case
Input 1
30
50
5
Output 1
There is a gas hog
Input 2
40.5
80.5
1.5
Output 2
Fuel Economy
Input 3
30
0
5
Output 3
You have entered 0
My code:
#include<stdio.h>
struct Car
{
float startKm;
float endKm;
float litres;
};
int main()
{
struct Car c;
float m;
scanf("%f",&c.startKm);
scanf("%f",&c.endKm);
scanf("%f",&c.litres);
m=(c.endKm-c.startKm)/c.litres;
if(c.startKm<=0||c.endKm<=0||c.litres<=0)
{
printf("You have entered 0"); return 0;
}
else if(m<=15)
{
printf("There is a gas hog");
}
else if(m>=30)
{
printf("It is an economy car");
}
else
{
printf("Fuel Economy");
}
return 0;
}
These are the test cases(unknown):
These is my evaluation output:
PS: I am facing similar problems in many such programs with several test cases.
I also asked a similar question Cannot identify error with code, failing a test case
It would be helpful if someone suggests how to approach such unknown test cases.

If I'm not mistaken you should be able to start from 0 km. I went ahead and tried my own test case:
Starting km 0, Ending km 25, Liters used 1
if(c.startKm < 0 || c.endKm <= c.startKm || c.litres <= 0)

Related

Correct outputs but codechef says wrong while submitting the code

Link to the problem : https://www.codechef.com/problems/HS08TEST
Description
Pooja would like to withdraw X $US from an ATM. The cash machine will only accept the transaction if X is a multiple of 5, and Pooja's account balance has enough cash to perform the withdrawal transaction (including bank charges). For each successful withdrawal the bank charges 0.50 $US. Calculate Pooja's account balance after an attempted transaction.
Input
Positive integer 0 < X <= 2000 - the amount of cash which Pooja wishes to withdraw.
Nonnegative number 0<= Y <= 2000 with two digits of precision - Pooja's initial account balance.
Output
Output the account balance after the attempted transaction, given as a number with two digits of precision. If there is not enough money in the account to complete the transaction, output the current bank balance.
Example - Successful Transaction
Input:
30 120.00
Output:
89.50
Example - Incorrect Withdrawal Amount (not multiple of 5)
Input:
42 120.00
Output:
120.00
Example - Insufficient Funds
Input:
300 120.00
Output:
120.00
I unable to find any incorrect output when I change the parameters in transaction function but still I am unable to submit it successfully due to some error which I am not able to find. This is my first try with codechef or in fact with any competitive programming so any help will be appreciated.Here's my code:
#define count 0.5
float transaction(int , float);
int main(void)
{
float transaction(int x, float acc_bal)
{
float z=acc_bal-(x+count);
if(x<acc_bal)
{
if(x%5==0)
{
printf("%.2f",z);
}
}
if(x%5!=0)
{
printf("%0.2f",acc_bal);
}
}
transaction(42,120.00);
}
Functions inside functions is not standard C. Some compilers supports it, but then you rely on compiler extensions. Do like this:
#include <stdio.h>
#define count 0.5
float transaction(int x, float acc_bal)
{
float z=acc_bal-(x+count);
if(x<acc_bal)
{
if(x%5==0)
{
printf("%.2f",z);
}
}
if(x%5!=0)
{
printf("%0.2f",acc_bal);
}
}
int main(void)
{
transaction(42,120.00);
}
But your code is unnecessarily messy and is missing the case where x is greater than the balance. Also, it does not need to be declared as a float. I would write like this instead:
void transaction(int x, float acc_bal)
{
const float count = 0.5;
float after=acc_bal-(x+count);
if(x%5 == 0 && after>=0.0) {
printf("%.2f\n",after);
} else {
printf("%0.2f\n",acc_bal);
}
}
Besides the function-in-function stuff and a missing return value (which isn't used btw), the problem is that you never check if the account goes negative.
Check what happens if you call your code with transaction(100,100.45);
Instead try like:
#define count 0.5
void transaction(int x, float acc_bal)
{
float z = acc_bal - count - x; // z will be new balance if the transaction is made
if (z >= 0 && x % 5 == 0) // check if the transaction can be made
{
acc_bal = z; // it could... so update balance
}
printf("%0.2f\n",acc_bal); // print current balance
}
int main(void)
{
transaction(100,100.45); // not ok - can't pay bank charges
transaction(99, 100.45); // not ok - x is not a multiple of 5
transaction(95, 100.55); // ok
}
Output:
100.45
100.45
5.05
The code in the question exhibits several deviations and potential deviations from the problem specification:
The program does not correctly test whether a transaction can be completed, because it tests whether the requested amount is less than the account balance instead of whether the requested amount plus the withdrawal fee is less than or equal to the balance.
It is not known that float has sufficient precision to represent the bank balance.
The program fails to end output lines with a newline character. (Although the problem statement does not state this explicitly, it may be expected implicitly.)
The program fails to include <stdio.h>.

while loop for scanning user input table into array

I am a super unintuitive beginner programming student working on a homework assignment. The program is to take an input table of hockey teams and game stats, calculate "points", and then output the table organized in a different way, with additional columns for points and games played.
So far, I haven't made it past scanning the input. With my while loop, I'm trying to first determine if the string is a conference name or a team name and then scan and store the subsequent table values accordingly. I'm just trying to print the same table back out at this point, but when i copy/paste the input input table which was given, I get no output, and when I manually type it in, it comes out suuper weird.
The input table looks something like this:
Conference1_Name 3 (teams in conference)
Team_1_Name 31 15 2 2 (wins, losses, ot losses, shootout losses)
Team_2_Name 24 21 1 0
Team_3_Name 27 19 0 2
Conference2_Name 4
Team_4_Name 30 15 1 1
...
aaand this is my code so far...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
int main(void){
int n=0, N=25, nE=0, nW=0, i, w[n], l[n], otl[n], sol[n], gp[n], pts[n];
char input[30], team[n][30];
printf("Enter conference data\n");
setvbuf(stdout,NULL,_IONBF,0);
while(n<=N){
scanf("%s", input);
if (0==strcmp(input, "Eastern_Conference")) {
scanf("%d", &nE);
continue; //does not count eastern conference as a team, but stores number of teams, and does not increment n
}
if (0==strcmp(input, "Western_Conference")) {
scanf("%d", &nW);
continue; //does not count western conference as a team, but stores number of teams, and does not increment n
}
if (0==strcmp(input, "EOD")) break;
//originally i had a statement like: if (nE>0 && nW>0){N=nE+nW;) so that the loop condition n<N will break the loop on it's own but thought maybe EOD would simplify it and fix my problem//
strcpy(team[n], input);
scanf("%d%d%d%d", &w[n], &l[n], &otl[n], &sol[n]);
gp[n]=w[n]+l[n];
pts[n]=(2*w[n])+otl[n]+sol[n];
n++;
} //so we have input the data and calculated points
printf("\n%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "WHL", "GP", "W", "L", "OTL", "SL", "PTS");
for(i=0; i<n; i++){
printf("%s\t%d\t%d\t%d\t%d\t%d\t%d\n", team[i], gp[i], w[i], l[i], otl[i], sol[i], pts[i]);
}
return EXIT_SUCCESS;
}

Galton Box/Bean Machine-C

I want to code a simple bean machine program. The program will accept user input for the number of balls and the number of slots, and will calculate the path of each ball. The number of balls in each slot will be printed as a histogram as well.
I tried my best to keep the code short and sweet, yet the best I have managed is 112 lines long. When I ran my code, I received no errors. However, the output seems to have run into some sort of an infinity loop (The '#' symbol which was used to represent numbers in the histogram keeps on printing forever for some reason unknown to me).
Apparently, there is something wrong with my logic somewhere... or a silly little mistake in syntax(but it would have shown up as error, wouldn't it?)... In a nutshell, I cannot figure out exactly what is the problem. (I attempted to walk through the whole code process from start to finish, but my mind kept getting tangled up somewhere in the middle of the code, nowhere near the end of the code either).
Where exactly does my logic go wrong?(Or have I taken the wrong approach to the whole problem?) I do not wish to know the correct code, so that I am able to learn during the whole process of re-editing my code.
Any help (hopefully no model-code answers though), even as a single comment, is tremendously appreciated! :)
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdbool.h>
#include <time.h>
//Pls excuse my extensive use of libraries even though I don't really use them
int intchecker(float x)
{
if (floor(x)==x && ceilf(x)==x)
{
return 0;
}
else {
return 1;
}
}
int main(){
char line[] = " +----+----+----+----+----+----+----+----+----+----+---+";
char numbers[] = " 0 5 10 15 20 25 30 35 40 45 50";
float balls,slots;
int slotarry[9],tlevel,ballnum,column,lcounter=0,slotsduplicate=1,y;//tlevel-number of levels in the triangle
srand(time(NULL));
int r;
printf("==========================================================\nGalton Box Simulation Machine\n==========================================================\n");
printf("Enter the number of balls [5-100]: ");
scanf("%f",&balls);
while (balls>100 || balls<5) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
while (intchecker(balls)==1) {
printf("\nInput is not an integer. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
printf("Enter the number of slots [2-10] : ");
scanf("%f",&slots);
while (slots>10 || slots<2) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
while (intchecker(slots)==1) {
printf("\nHow can there be a fraction of a slot? Please re-enter slot number.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
tlevel=slots-1;
for(ballnum=1,column=0;balls>0;balls--,ballnum++,column++){
if (column%5==0){
printf("\n");
}
if (ballnum<10){
printf("[0%d]",ballnum);
}
else{
printf("[%d]",ballnum);
}
for(;tlevel>0;tlevel--){
r = rand() % 2;
if (r==0){
printf("R");
}
else {
printf("L");
lcounter++;
}
}
slotarry[lcounter]++;
tlevel=slots-1;
lcounter=0;
printf(" ");
}
printf("\n\n%s",numbers);
printf("%s",line);
char line2[] = "\n +----+----+----+----+----+----+----+----+----+----+---+";
for(;slotsduplicate<=slots;slotsduplicate++){
if (slotsduplicate<10){
printf("0%d|",slotsduplicate);
}
else{
printf("%d|",slotsduplicate);
}
y=slotarry[slotsduplicate];
if (y==0){
printf(" 0");
}
else{
for (;y>0;y--){
printf("#");
}
printf(" %d",slotarry[slotsduplicate]);
}
printf("%s",line2);
}
return 0;
}
Note:This is not completely error-free. This is just my first draft. I just wish to find out why there is an infinite loop.
Here's how I found the problem. First of all, I think it is a bit of a code smell to have a for loop without anything in the initial assignment section. Couple that with the fact that it seems to print # forever, and it looks like y has a garbage value at the beginning of the loop to print the #s.
So I ran your code in the debugger and paused it when it started printing loads of hashes. I checked the value of y and sure enough it was some unfeasibly high number.
Then I checked where y comes from and found you get it from slotarray. I printed it in the debugger and found that all the values in it were unfeasibly high or massively negative numbers. Obviously, slotarray wasn't being initialised correctly, so I looked for where it was initialised and bingo!
Stack variables (of which slotarray is one) must be explicitly initialised in C. I fixed your code with a call to memset.
The whole debugging process I have just outlined took something less than a minute.
ETA As #EOF points out, there is another bug in that slotarray is defined to contain nine slots (indexed 0 - 8) but you allow people to enter 10 slots. This is a buffer overflow bug.

Get program to return an error message and return to start of program if value entered is outside range

I'm a complete beginner with C and am currently trying to write a program where the user can enter results from football league games and calculate the teams' scores after each game.
There are 6 teams in the league and the user is required to choose a team at the start of the program in order to input a score for that team. What I would like to do is have the program return an error message if the user enters a value that is not between 1 and 6.
I've tried two different approaches but I'm not sure if either are in the right direction. One approach is shown below for the home team.
#include <stdio.h>
int main(void)
{
int h=0; /*Home team number*/
int a=0; /*Away team number*/
int hgoals=0; /*Goals scored by home team*/
int agoals=0; /*Goals scored by away team*/
/*User inputs home team number*/
printf("Home team number: ");
scanf_s("%d",&h);
/*Returns error message if home team number is not between 1 & 6*/
if(1<!h<!6){
printf("Please enter a number between 1 & 6\n");
}
return 0;
}
The other idea I had was to use an if statement where if the number entered is between 1 & 6 then nothing would happen, and use else to print the error message if the number is not between 1 & 6, but I'm not sure how to make an if statement that does nothing. I'm also thinking that I would have to put the entire program inside a loop to get it to restart if the number is not between 1 & 6.
Any help is appreciated!
Change the condition in the if statement :
if(h < 1 || h > 6)
printf("Please enter a number between 1 and 6\n");

C Primer 5th - Task 14-6

A text file holds information about a softball team. Each line has data arranged as follows:
4 Jessie Joybat 5 2 1 1
The first item is the player's number, conveniently in the range 0–18. The second item is the player's first name, and the third is the player's last name. Each name is a single word. The next item is the player's official times at bat, followed by the number of hits, walks, and runs batted in (RBIs). The file may contain data for more than one game, so the same player may have more than one line of data, and there may be data for other players between those lines. Write a program that stores the data into an array of structures. The structure should have members to represent the first and last names, the at bats, hits, walks, and RBIs (runs batted in), and the batting average (to be calculated later). You can use the player number as an array index. The program should read to end-of-file, and it should keep cumulative totals for each player.
The world of baseball statistics is an involved one. For example, a walk or reaching base on an error doesn't count as an at-bat but could possibly produce an RBI. But all this program has to do is read and process the data file, as described next, without worrying about how realistic the data is.
The simplest way for the program to proceed is to initialize the structure contents to zeros, read the file data into temporary variables, and then add them to the contents of the corresponding structure. After the program has finished reading the file, it should then calculate the batting average for each player and store it in the corresponding structure member. The batting average is calculated by dividing the cumulative number of hits for a player by the cumulative number of at-bats; it should be a floating-point calculation. The program should then display the cumulative data for each player along with a line showing the combined statistics for the entire team.
team.txt (text file I'm working with):
4 Jessie Joybat 5 2 1 1
4 Jessie Joybat 7 3 5 3
7 Jack Donner 6 3 1 2
11 Martin Garder 4 3 2 1
15 Jaime Curtis 7 4 1 2
2 Curtis Michel 3 2 2 3
9 Gillan Morthim 9 6 6 7
12 Brett Tyler 8 7 4 3
8 Hans Gunner 7 7 2 3
14 Jessie James 11 2 3 4
12 Brett Tyler 4 3 1 3
Since I'm a beginner in C, either I misinterpreted the task from what was asked originally or it's unfairly complex (I believe the former is the case). I'm so lost that I can't think of the way how could I fill in by the criteria of index (player number) every piece of data, keep track of whether he has more than one game, calculate and fetch bat average and then print.
What I have so far is:
#define LGT 30
struct profile {
int pl_num;
char name[LGT];
char lname[LGT];
int atbat[LGT/3];
int hits[LGT/3];
int walks[LGT/3];
int runs[LGT/3];
float batavg;
};
//It's wrong obviously but it's a starting point
int main(void)
{
FILE *flx;
int i,jc,flow=0;
struct profile stat[LGT]={{0}};
if((flx=fopen("team.txt","r"))==NULL) {
fprintf(stderr,"Can't read file team!\n");
exit(1);
}
for( jc = 0; jc < 11; jc++) {
fscanf(flx,"%d",&i);
stat[i].pl_num=i;
fscanf(flx,"%s",&stat[i].name);
fscanf(flx,"%s",&stat[i].lname);
fscanf(flx,"%d",&stat[i].atbat[flow]);
fscanf(flx,"%d",&stat[i].hits[flow]);
fscanf(flx,"%d",&stat[i].walks[flow]);
fscanf(flx,"%d",&stat[i].runs[flow]);
flow++;
}
}
Advice 1: don't declare arrays like atbat[LGT/3].
Advice 2: Instead of multiple fscanf you could read the whole line in a shot.
Advice 3: Since the number of players is limited and the player number has a good range (0-18), using that player number as an index into the struct array is a good idea.
Advice 4: Since you need cumulative data for each player (no need to store his history points), then you don't need arrays of integers, just an integer to represent the total.
So:
#include <stdio.h>
#define PLAYERS_NO 19
typedef struct
{
char name[20+1];
char lastName[25+1];
int atbat;
int hits;
int walks;
int runs;
float batavg;
} Profile;
int main(int argc, char** argv)
{
Profile stats[PLAYERS_NO];
int i;
FILE* dataFile;
int playerNo;
Profile tmpProfile;
int games = 0;
for(i=0; i<PLAYERS_NO; ++i)
{
stats[i].name[0] = '\0';
stats[i].lastName[0] = '\0';
stats[i].atbat = 0;
stats[i].hits = 0;
stats[i].walks = 0;
stats[i].runs = 0;
}
dataFile = fopen("team.txt", "r");
if ( dataFile == NULL )
{
fprintf(stderr, "Can't read file team!\n");
exit(1);
}
for(i=0; i<PLAYERS_NO && !feof(dataFile); ++i, ++games)
{
fscanf(dataFile, "%d", &playerNo);
if ( playerNo <0 || playerNo > PLAYERS_NO )
{
fprintf(stderr, "Player number out of range\n");
continue;
}
fscanf(dataFile, "%s %s %d %d %d %d",
&tmpProfile.name,
&tmpProfile.lastName,
&tmpProfile.atbat,
&tmpProfile.hits,
&tmpProfile.walks,
&tmpProfile.runs);
printf("READ: %d %s %s %d %d %d %d\n",
playerNo,
tmpProfile.name,
tmpProfile.lastName,
tmpProfile.atbat,
tmpProfile.hits,
tmpProfile.walks,
tmpProfile.runs);
strcpy(stats[playerNo].name, tmpProfile.name);
strcpy(stats[playerNo].lastName, tmpProfile.lastName);
stats[playerNo].atbat += tmpProfile.atbat;
stats[playerNo].hits += tmpProfile.hits;
stats[playerNo].walks += tmpProfile.walks;
stats[playerNo].runs += tmpProfile.runs;
}
/* exercise: compute the average */
fclose(dataFile);
for(i=0; i<PLAYERS_NO; ++i)
{
if ( stats[i].name[0] == '\0' )
continue;
printf("%d %s %s %d %d %d %d\n",
i,
stats[i].name,
stats[i].lastName,
stats[i].atbat,
stats[i].hits,
stats[i].walks,
stats[i].runs);
}
return 0;
}
The first rule of programming: Divide and conquer.
So you need to identify individual operations. One such operation is "load one row of input", another is "look up a player". If you have some of those operations (more will come up as you go), you can start building your program:
while( more_input ) {
row = load_one_row()
player = find_player( row.name )
if( !player ) {
player = create_player( row.name )
add_player( player )
}
... do something with row and player ...
}
when you have that, you can start to write all the functions.
An important point here is to write test cases. Start with a simple input and test the code to read a row. Do you get the correct results?
If so, test the code to find/create players.
The test cases make sure that you can forget about code that already works.
Use a framework like Check for this.
If I were doing this, I'd start with a structure that only held one "set" of data, then create an array of those structs:
struct profile {
char name[NAMELEN];
char lname[NAMELEN];
int atbat;
int hits;
int walks;
int runs;
float batavg;
};
Since you're using the player's number as the index into an array, you don't need to store it into the structure too.
I think that will simplify the problem a little bit. You don't need to store multiple data items for a single player -- when you get a duplicate, you just ignore some of the new data (like the names, which should be identical) and sum up the others (e.g., at-bats, hits).

Resources