WeatherData is #3 from the from the 2023 AP Computer Science A Free Response problems.
https://apcentral.collegeboard.org/media/pdf/ap23-frq-comp-sci-a.pdf
Part (a) cleanData method
public void cleanData(double lower, double upper)
{
int i = 0;
while(i < temperatures.size())
{
Double t = temperatures.get(i);
if(t.compareTo(lower) < 0 || t.compareTo(upper) > 0)
temperatures.remove(i);
else
i++;
}
}
The use of compareTo is optional. Java will automatically unbox the Double objects into double.
Part (b) longestHeatWave method (original solution)
public int longestHeatWave(double threshold)
{
int almostCurrentLength = 0;
int almostMaxLength = 0;
for(int i = 1; i < temperatures.size(); i++)
{
Double before = temperatures.get(i - 1);
Double current = temperatures.get(i);
if(before.compareTo(threshold) > 0 &&
current.compareTo(threshold) > 0)
{
// in heatwave
almostCurrentLength++;
if(almostCurrentLength > almostMaxLength)
almostMaxLength = almostCurrentLength;
}
else
almostCurrentLength = 0;
}
return almostMaxLength + 1;
}
almostCurrentLength stores 1 less than the length of the heatwave that includes the element at i, or 0 if the element at i is not the second or subsequent element of a heatwave. (almostCurrentLength excludes the first element of the heatwave.)
almostMaxLength stores 1 less than the length of the longest known heatwave, or 0 if a heatwave has not yet been encountered.
This is a variation of find the minimum or maximum. almostMaxLength starts at 0 because no heatwave has yet been encountered. (It is also possible to start almostMaxLength at 1 since the problem description guarantees at least 1 heatwave.) The length of each heatwave encountered is compared against the length of the longest known heatwave.
When I originally approached this problem, I thought of it as being similar to the NumberCube getLongestRun method. My original solution to longestHeatWave is based on updating almostCurrentLength if and only if the value at i is part of a heatwave. This requires comparing consecutive elements and addressing skipping the first element of each heatwave. The additional solution below is more straightforward.
Part (b) longestHeatWave method (additional solution)
public int longestHeatWave(double threshold)
{
int hotInARow = 0;
int maxHotInARow = 0;
for(int i = 0; i < temperatures.size(); i++)
{
if(temperatures.get(i).compareTo(threshold) > 0)
{
hotInARow++;
if(hotInARow > maxHotInARow)
maxHotInARow = hotInARow;
}
else
hotInARow = 0;
}
return maxHotInARow;
}
As others (too many to credit) have pointed out, it is not necessary to compare consecutive elements within a single run of the loop. This solution finds the length of the longest run of days that exceed threshold, even if that length is 0 or 1. The problem guarantees that at least 1 heatwave exists, so the length of the longest run will always be >= 2.
Java files with test code
ThreeTest.java includes JUnit 5 test code with the examples from the problem and 1 additional easily missed example (longest heatwave is at the end). See Running JUnit 5 tests.
WeatherData.java
ThreeTest.java
Additional resources
2023 AP CS Exam Free Response Solutions
- AppointmentBook Free Response Solution
- Sign Free Response Solution
- BoxOfCandy Free Response Solution
Help & comments
Get help from AP CS Tutor Brandon Horn