Part A: simulate()
import java.util.Random;
class FrogSimA {
private int goalDistance = 24;
private int maxHops = 5;
private Random rand = new Random(42);
public int hopDistance() {
return rand.nextInt(16) - 5; // range: -5 to 10
}
public boolean simulate() {
int position = 0;
for (int i = 0; i < maxHops; i++) {
position += hopDistance();
if (position < 0) {
return false;
}
if (position >= goalDistance) {
return true;
}
}
return false;
}
}
public class PartA {
public static void main(String[] args) {
FrogSimA frog = new FrogSimA();
for (int i = 1; i <= 5; i++) {
System.out.println("Run " + i + ": " + frog.simulate());
}
}
}
PartA.main(null);
Run 1: false
Run 2: false
Run 3: false
Run 4: true
Run 5: false
Each call is a single independent simulation. The frog succeeded on run 4 and failed the rest — either by going negative or exhausting all 5 hops without reaching position 24.
Part B: runSimulations(int num)
import java.util.Random;
class FrogSimB {
private int goalDistance = 24;
private int maxHops = 5;
private Random rand = new Random();
public int hopDistance() {
return rand.nextInt(16) - 5; // range: -5 to 10
}
public boolean simulate() {
int position = 0;
for (int i = 0; i < maxHops; i++) {
position += hopDistance();
if (position < 0) {
return false;
}
if (position >= goalDistance) {
return true;
}
}
return false;
}
public double runSimulations(int num) {
int successes = 0;
for (int i = 0; i < num; i++) {
if (simulate()) {
successes++;
}
}
return (double) successes / num;
}
}
public class PartB {
public static void main(String[] args) {
FrogSimB frog = new FrogSimB();
System.out.println("Success proportion: " + frog.runSimulations(1000));
}
}
PartB.main(null);
Success proportion: 0.149
Out of 1000 simulations, about 14.9% succeeded. This makes sense given how difficult it is to reach position 24 in only 5 hops with random distances ranging from -5 to 10 — the frog needs consistently large positive hops without any negative ones tanking the run early.
Key Takeaways
- Loop-based simulation:
simulate()uses aforloop bounded bymaxHops— not awhile(true)— so it naturally terminates after a fixed number of hops. - Early exit conditions: Return
falseimmediately when position goes negative (fell in water); returntrueimmediately when position meets or exceeds the goal. Don’t wait for the loop to finish. - Reusing methods:
runSimulations()simply callssimulate()repeatedly and counts successes — no need to reimplement the hop logic. Reuse existing methods on the object. - Proportion vs. count: The return type of
runSimulations()isdouble, so cast before dividing:(double) successes / num. Integer division would return0almost always. - Off-by-one awareness: The hop range is -5 to 10 inclusive (
rand.nextInt(16) - 5), and the goal check is>= goalDistance, not>. Make sure boundary conditions match the problem spec exactly.