Best Fare Calculator Project

Can someone explain the String method getBestFare() to me. Especially I do not understand why int winningIndex is 0. Thank you in advance !!!

Task:
Unbenannt

import java.util.Arrays;

public class TransitCalculator {

String[] fareOptions = {"Pay-per-ride", "7-day Unlimited", "30-day Unlimited"};
double[] fares = {2.75, 33.0, 127.0};

int rides;
int days;

public TransitCalculator(int numRides, int numDays) {

    rides = numRides;
    days = numDays;

}

public double unlimited7Price() {

    double sevenDayPurchases = Math.ceil(days / 7.0);
    double total7DayCost = sevenDayPurchases * fares[1];

    return total7DayCost / rides;

}

public double[] getRidePrices() {

    double pprPrice = fares[0];
    double unlimited7Price = unlimited7Price();
    double unlimited30Price = fares[2] / rides;
  
    double prices[] = {pprPrice, unlimited7Price, unlimited30Price};
    return prices;
  
}

public String getBestFare() {

    double[] ridePrices = getRidePrices();
    int winningIndex = 0;

    for (int i = 0; i < ridePrices.length; i++) {
        
        if (ridePrices[i] < ridePrices[winningIndex]){

            winningIndex = i;

        }

    }

    return "You should get the " + fareOptions[winningIndex] + " option at $" + Math.round(ridePrices[winningIndex] * 100.0) / 100.0 + " per ride.";
}

public static void main(String[] args) {

    int myRides = 12;
    int myDays = 5;

    TransitCalculator transitCalc = new TransitCalculator(myRides, myDays);
    
    System.out.println(transitCalc.getBestFare());

}

}

This prepares an array of prices, utilizing the getRidePrices() method.

This initializes a variable that will be used as an index for ridePrices.

for-loop. it will start from i=0, up to size of ridePrices, and adding 1 to 1 at every iteration.

for first iteration: check if ridePrices[0] < ridePrices[0]. it will be false, because it is comparing with the same values… but the second iteration will check if ridePrices[1] < ridePrices[0], because it incremented i by 1, but winningIndex remained the same.

When this check is True, then:

which means that winningIndex value will change and become that value that was used for i, and that will be the new lowest fare.

If not clear, this can help you understand:
double ridePrices = [3,2,5,1,7]
int winningIndex = 0

let’s iterate from 0 to 4 (because we will iterate until i < lenght, so when it gets to size 5, it will not iterate)

first iteration: i = 0 … is 3 < 3? False
second iteration: i = 1… is 2 < 3? True -> winningIndex = 1
third iteration: i = 2… is 5 < 2? False
forth iteration: i=3… is 1 < 2? True -> winningIndex = 3
fifth iteration: i = 4… is 7 < 1? False

the loop stops here as i = 5 and it will only allow it to go if i < ridePrices.length, so i < 5…
and winningIndex is 3.
checking the array that I provided, [3,2,5,1,7], the index #3 is 1, the lowest value.

3 Likes

Thank you so much, quite understandable. But I have one question about your examaple:

first iteration: i = 0 … is 3 < 3 ? False
second iteration: i = 1… is 2 < 3 ? True -> winningIndex = 1
third iteration: i = 2… is 5 < 2 ? False
forth iteration: i=3… is 1 < 2 ? True -> winningIndex = 3
fifth iteration: i = 4… is 7 < 1 ? False

Why are you comparing with these numbers for each iteration ? Why exactly these ? :grinning:

1 Like

the comparison used is ridePrices[i] < ridePrices[winningIndex] , right?
so, the numbers you highlighted are ridePrices[winningIndex] values.
as winningIndex starts as 0…

…winningIndex[0] = 3 (position 0 of my array [3,2,5,1,7])

once winningIndex becomes 1, it will use position 1 of my array [3,2,5,1,7], which now is 2…
on the last step, winningIndex becomes 3, so I use position 3 of the array, which is 1.

The winningIndex position become the value of i, when the condition is true:

2 Likes

I think I just confused myself.

If int winningIndex = 0, then my comparisons have to looked like this:

Based on your expample:

double ridePrices = [3,2,5,1,7]
int winningIndex = 0

for (int i = 0; i < ridePrices.length; i++) {

if (ridePrices[i] < ridePrices[winningIndex]){

winningIndex = i;

}

so,

i = 0…ridesPrices[0] < ridesPrices[0]……3 < 3
i = 1…ridesPrices[1] < ridesPrices[0]…….2 < 3 ----> winningIndex = 1
i = 2…ridesPrices[2] < ridesPrices[0]……5 < 3
i = 3…ridesPrices[3] < ridesPrices[0]……1 < 3 -----> winningIndex = 3
i = 4…ridesPrices[4] < ridesPrices[0]……7 < 3

??? Please correct me

Can your rewrite your example so I can see what you exactly do, I think I get it then :grinning: :grinning: :grinning: thank you so much.

first iteration: i = 0 … is 3 < 3? False
second iteration: i = 1… is 2 < 3? True -> winningIndex = 1
third iteration: i = 2… is 5 < 2 ? False
forth iteration: i=3… is 1 < 2 ? True -> winningIndex = 3
fifth iteration: i = 4… is 7 < 1 ? False

There is still a misunderstanding in the third, forth and fifth iteration :crying_cat_face:

1 Like

I think you might find it easier to understand if you adjust your getBestFare() function as follows:

public String getBestFare() {

    double[] ridePrices = getRidePrices();
    int winningIndex = 0;

    for (int i = 0; i < ridePrices.length; i++) {
        System.out.println("For-loop interation " + i);
        System.out.println("Comparing " + fareOptions[i] + " ($" + ridePrices[i] + ") with current best " + fareOptions[winningIndex] + " ($" + ridePrices[winningIndex] + ").");
        if (ridePrices[i] < ridePrices[winningIndex]){
            System.out.println("Compared price beats previous best, recording new best price!");
            winningIndex = i;
        }

    }

    return "You should get the " + fareOptions[winningIndex] + " option at $" + Math.round(ridePrices[winningIndex] * 100.0) / 100.0 + " per ride.";
}

Note how I have added lines inside the for loop to show you, on the console, the current iteration (the value of i), as well as the fares being compared.

If we run this, we get the following:

For-loop interation 0
Comparing Pay-per-ride ($2.75) with current best Pay-per-ride ($2.75).
For-loop interation 1
Comparing 7-day Unlimited ($2.75) with current best Pay-per-ride ($2.75).
For-loop interation 2
Comparing 30-day Unlimited ($10.583333333333334) with current best Pay-per-ride ($2.75).
You should get the Pay-per-ride option at $2.75 per ride.

The winningIndex starts as being 0, so the “best price” starts out as being the pay-per-ride option at $2.75. We then compare the other calculated prices to see if any work out better value.

We could, if we wanted to, set the winningIndex to a value other than 0… but pay-per-ride is the cheapest ticket option, and we want to know if any of the others offer a lower price per ride than the standard per-ride fare.

Does that help at all?

Edit: I really need a coffee… interation?! :man_facepalming:

I’m not changing it. I’ll own that typo! :stuck_out_tongue:

1 Like

the reason why it doesn’t get stuck comparing with 3 is because of this:

winningIndex will get the value of i, when the condition above it is true.
so check again the example that I gave you… winningIndex is getting the value that “i” had at the moment, that’s why it is changing to 2, and then 1.

2 Likes

Yes this helps me alot, thank you both :smile:

1 Like

This topic was automatically closed 18 hours after the last reply. New replies are no longer allowed.