Prof: There are actually a lot of ways to do this in Java. We’ll use a loop; it’s one of the most common and it works well with arrays.
Student: Finally, real code!
Prof: Hey, everything up to now was extremely real, we watched it all run and everything!
Student: Just show me the loop, please!
Prof: Fine. First tell me the plan for this method body, though.
Student: The plan?
Prof: Yeah. Loop plans over arrays will often say something like “for each element of the array, the code will…”
Student: OK. For each point, the code will get its distance to the target and check if it’s closer than… the other… closer than something.
Prof: Right, we need a point of comparison. This is a kind of accumulator loop because it’s going to track a value that “accumulates” some information over time. Here I’d call it a best-so-far accumulator, which tracks “the closest point we’ve seen so far”.
Student: OK, so for each point, the code will get its distance to the target and check if it’s closer than the closest point we’ve seen so far.
Prof: And what does it do if we get something closer?
Student: I guess it… updates it?
Prof: Cool! Let’s put it all together.
Student: Wow, that’s so interesting. There’s a lot going on!
Prof: Indeed. We just saw two things at once:
- Assignment – the definition of
closeststarts as the first value in the array, and then changes when we useclosest = p - A
forloop – the syntaxfor(Point p: points) { /* loop body */ }. It runs the loop body once for each element ofpoints, and each time it runs, the next element is stored inp.
These two things tend to go together in programming: many loops that we want to write only work with assignment.
And one other bit of jargon – a mathy name for a best-so-far loop that returns the element that is the “smallest” in some way is argmin, which you might see in other contexts. Here that “something” is the distance to a target.
Student: Cool!
Practice
Pizza has the area and betterDeal methods from before. Write the whole body of bestDeal, which returns the pizza in the order with the best (lowest) price per square inch.record Pizza(double inches, int costCents) {
double area() {
double radius = inches / 2;
return radius * radius * Math.PI;
}
boolean betterDeal(Pizza other) {
return costCents / area() < other.costCents / other.area();
}
}
record PizzaOrder(Pizza[] pizzas) {
Pizza bestDeal() {
}
}
Pizza small = new Pizza(10, 500);
Pizza big = new Pizza(16, 1000);
Pizza medium = new Pizza(12, 900);
Pizza[] partyPizzas = { small, big, medium };
PizzaOrder party = new PizzaOrder(partyPizzas);
Pizza[] lunchPizzas = { medium, small };
PizzaOrder lunch = new PizzaOrder(lunchPizzas);
Pizza partyBest = party.bestDeal();
Pizza lunchBest = lunch.bestDeal();
double area() {
double radius = inches / 2;
return radius * radius * Math.PI;
}
boolean betterDeal(Pizza other) {
return costCents / area() < other.costCents / other.area();
}
}
record PizzaOrder(Pizza[] pizzas) {
Pizza bestDeal() {
}
}
Pizza small = new Pizza(10, 500);
Pizza big = new Pizza(16, 1000);
Pizza medium = new Pizza(12, 900);
Pizza[] partyPizzas = { small, big, medium };
PizzaOrder party = new PizzaOrder(partyPizzas);
Pizza[] lunchPizzas = { medium, small };
PizzaOrder lunch = new PizzaOrder(lunchPizzas);
Pizza partyBest = party.bestDeal();
Pizza lunchBest = lunch.bestDeal();