John R
John R

Reputation: 389

C math order of operation

I have an assignment that I have been working on. My code appears to have the correct math operations and in the correct order (at least sequence wise), but my answers are a little screwy. I get parts of each question right according to my input values, but never the same part(s) as input values change. Is there something about C order of operations that I am missing that is causing this?

I feel like the problem is at

intPeople = intCarCounter * intTrainCounter * CAR_CAPACITY;

For sample run #3 I get 120 people for the first two inputs (exactly 20 more than the correct answers) and the surplus number is what should be in sample run #4. On the third input I get 112 people which is again the correct answer for sample run #4. Finally, on sample run #4 I get 128 people (16 more than the correct answer) and the surplus number is what should be in sample run #3. Any ideas?

Assignment: http://cop3223.blogspot.com/2013/01/problem-c-roller-coaster-design-coasterc.html

My Code:

#include <stdio.h>
#include <stdlib.h>
#define FIRST_CAR_LENGTH 10
#define NORMAL_CAR_LENGTH 8
#define CAR_CAPACITY 4

int main(void)
{
    /* Initialize Variables */
    int intTrack,intMaxTrainSize,intActualTrainSize,intPeople,intCarCounter,intTrainCounter,n;

    /* Ask user for value of N */
    printf("What is the value for N?> ");
    scanf("%d",&n);
    for (int i=0; i<n;i++)
    {
        /* Ask user for total length of track */
        printf("\nWhat is the total length of the track, in feet?> ");
        scanf("%d",&intTrack);

        /* Ask user for maximum length of each train */
        printf("What is the maximum length of a train, in feet?> ");
        scanf("%d",&intMaxTrainSize);

        /* Set/Reset initial values of intActualTrainSize, intCarCounter and intTrainCounter */
        /* Each train will begin with FIRST_CAR_LENGTH -> intActualTrainSize=FIRST_CAR_LENGTH */
        /* Each train will begin with 1 car -> intCarCounter=1 */
        /* Train counter will begin at 0 -> intTrainCounter=0 */
        intActualTrainSize=FIRST_CAR_LENGTH;
        intCarCounter=1;
        intTrainCounter=0;

        /* Continue to add additional cars using NORMAL_CAR_LENGTH until the maximum train size has been reached */
        /* Count how many NORMAL_CAR_LENGTH cars are added -> intCarCounter++*/
        while (intActualTrainSize < intMaxTrainSize)
        {
            intActualTrainSize=intActualTrainSize+NORMAL_CAR_LENGTH;
            intCarCounter++;
        } 

        /* Count how many trains can be added until 25% of the track is used up -> intTrainCounter++ */
        while (intTrainCounter*intActualTrainSize < (int)(intTrack*.25)) 
        {
            intTrainCounter++;
        }

        /* Count how many people can be on the track at one time -> intPeople = intCarCounter * intTrainCounter * CAR_CAPACITY */
        intPeople = intCarCounter * intTrainCounter * CAR_CAPACITY;
        printf("\nYour ride can have at most %d people on it at one time.",intPeople);

        if (intActualTrainSize>intMaxTrainSize)
            printf("\nMaximum Train Length has surplus of %d feet.\n",intActualTrainSize-intMaxTrainSize);
        else if (intMaxTrainSize==intActualTrainSize)
            printf("\nMaximum Length fits exactly.\n");
    }
    system("pause");
    return 0;
}

Upvotes: 2

Views: 424

Answers (4)

renonsz
renonsz

Reputation: 591

Type in variable names and one character variable names are not recommended. Incrementing a counter in a loop with a fix value is shipped with multiplication, no iteration needed. Actual train size exceeds maximum in last iteration of your loop. What if user provided max train size is under FIRST_CAR_LENGTH? Approachment of calculating actual train size first is right. Hassan's answer seems to be incorrect if surplus exists.

const double occ = 0.25;

int track;
int max_train;

int cap;
int num_car;
int num_train = 0;
int train = 0;

printf( "Length of track? "); scanf( "%d", &track );
printf( "Max length of train? "); scanf( "%d", &max_train );

num_car = std::max( 0, max_train - FIRST_CAR_LENGTH + NORMAL_CAR_LENGTH ) / NORMAL_CAR_LENGTH;
if( 0 < num_car )
{
    train = FIRST_CAR_LENGTH + NORMAL_CAR_LENGTH * ( num_car - 1 );
    num_train = ( int ) ( occ * track ) / train;
}
cap = CAR_CAPACITY * num_car * num_train;
printf( "Capacity: %d; Train surplus: %d\n", cap, max_train - train );

Upvotes: 0

hmatar
hmatar

Reputation: 2429

You used a loop to calcutate train counters and car counters, instead you could, as another alternative, use integer arithmetic to calculate those values. I have attached my solution which does not involve loops. It makes easier to debug. I am providing two versions. Version 1 sassumes integer division does no round-off. Version 2 is safer as it subtracts remainders before division.

    //VERSION 1:

    #include <stdio.h>

    #define FIRST_CAR_LENGTH 10
    #define NORMAL_CAR_LENGTH 8
    #define CAR_CAPACITY 4

    int main(void)
    {
      int N, i;
      int trackSize;
      int trainSize;
      int numberPeople;
      int numberCars;
      int trainsPerTrack;
      int surplus;

      printf("What is the value for N?");
      scanf("%d", &N);
      for(i=0; i < N; i++)
      {
         printf("What is the total length of the track, in feet?\n");
         scanf("%d", &trackSize);
         printf("What is the maximum length of a train, in feet?\n");
         scanf("%d", &trainSize);
         trainsPerTrack = trackSize / (4 * trainSize);
         numberCars = (trainSize -FIRST_CAR_LENGTH) / NORMAL_CAR_LENGTH + 1;

         numberPeople = trainsPerTrack * numberCars * CAR_CAPACITY;
         printf("Your ride can have at most %d people on it at one time.\n", numberPeople);

         surplus = (trainSize - FIRST_CAR_LENGTH) % NORMAL_CAR_LENGTH;
         if(surplus)
           printf("Maximum Train Length has surplus of %d feet\n\n", surplus);
         else
           printf("Maximum Length fits exactly\n\n");
      }
      return 0;
    }


VERSION 2:
#include <stdio.h>

#define FIRST_CAR_LENGTH 10
#define NORMAL_CAR_LENGTH 8
#define CAR_CAPACITY 4

int main(void)
{
  int N, i;
  int trackSize;
  int trainSize;
  int numberPeople;
  int numberCars;
  int trainsPerTrack;
  int surplus;

  printf("What is the value for N?");
  scanf("%d", &N);
  for(i=0; i < N; i++)
  {
     printf("What is the total length of the track, in feet?\n");
     scanf("%d", &trackSize);
     printf("What is the maximum length of a train, in feet?\n");
     scanf("%d", &trainSize);
     trainsPerTrack = (trackSize- (trackSize % (4*trainSize))) / (4 * trainSize);
     int forSmallerCars = trainSize - FIRST_CAR_LENGTH;
     numberCars = (forSmallerCars - (forSmallerCars % NORMAL_CAR_LENGTH)) / NORMAL_CAR_LENGTH + 1;

     numberPeople = trainsPerTrack * numberCars * CAR_CAPACITY;
     printf("Your ride can have at most %d people on it at one time.\n", numberPeople);

     surplus = (trainSize - FIRST_CAR_LENGTH) % NORMAL_CAR_LENGTH;
     if(surplus)
       printf("Maximum Train Length has surplus of %d feet\n\n", surplus);
     else
       printf("Maximum Length fits exactly\n\n");
  }
  return 0;
}

Upvotes: 2

Karthik T
Karthik T

Reputation: 31972

Not sure if it directly contributes, but you need to recheck the below

while (intActualTrainSize +NORMAL_CAR_LENGTH  <= intMaxTrainSize )
{                         ^^^^^^^^^^^^^^^^^^    
    intActualTrainSize=intActualTrainSize+NORMAL_CAR_LENGTH;
    intCarCounter++;
} 

Your code allows for Actual train size to overflow max train size, so that might be 10 of the extra 20. This check will ensure that you only add cars if it will STILL remain within the max.

Similarly with Train counter, which can also overflow.

Try to convert such while loops into math formulas if you can, more efficient and more readable.

Upvotes: 1

Floris
Floris

Reputation: 46435

Your train ends up too long in the line that says

    while (intActualTrainSize < intMaxTrainSize)
    {
        intActualTrainSize=intActualTrainSize+NORMAL_CAR_LENGTH;
        intCarCounter++;
    } 

Since you will execute this loop until the train is too long...

Upvotes: 0

Related Questions