(See the previous iteration.)
This time, I removed the stuff I don't need in my demo runner. Also, I consolidated some code that seemed DRY to me.
Simulation rules
- When a female arrives, she ensures that the seat is down before performing the urge. She leaves the seat down before exiting.
- When a male arrives to pee, he makes sure the seat is up and pees. After peeing, if we require all the visitors to put down the seat, the male puts it down. Otherwise, the seat remains upwards.
- When a male arrives to poo, the case 1 applies.
Here it goes:
package com.github.coderodde.simulation.toiletseat;
import java.util.Random;
public final class ToiletSeatSimulator {
private static enum Gender {
FEMALE,
MALE,
}
private static enum Operation {
PEE,
POOP,
}
private static enum SeatPosition {
UP,
DOWN,
}
private final int queueLength;
private final double femaleRatio;
private final double peeRatio;
private final boolean alwaysLeaveSeatDown;
private final Random random;
private SeatPosition seatPosition = SeatPosition.DOWN;
private int movements = 0;
public ToiletSeatSimulator(int queueLength,
double femaileProportion,
double urinationProportion,
boolean alwaysLeaveSeatDown,
Random random) {
this.queueLength = queueLength;
this.femaleRatio = femaileProportion;
this.peeRatio = urinationProportion;
this.alwaysLeaveSeatDown = alwaysLeaveSeatDown;
this.random = random;
}
public int simulate() {
for (int i = 0; i < queueLength; i++) {
performOperation(getRandomGender(),
getRandomOperation());
}
return movements;
}
private void performOperation(Gender gender, Operation operation) {
switch (operation) {
case POOP:
setSeatPosition(SeatPosition.DOWN);
return;
case PEE:
switch (gender) {
case FEMALE:
setSeatPosition(SeatPosition.DOWN);
return;
case MALE:
setSeatPosition(SeatPosition.UP);
if (alwaysLeaveSeatDown) {
setSeatPosition(SeatPosition.DOWN);
}
return;
}
}
}
private void setSeatPosition(SeatPosition seatPosition) {
if (this.seatPosition != seatPosition) {
this.seatPosition = seatPosition;
movements++;
}
}
private Gender getRandomGender() {
double coin = random.nextDouble(); // In the range [0, 1).
return coin < femaleRatio ? Gender.FEMALE : Gender.MALE;
}
private Operation getRandomOperation() {
double coin = random.nextDouble();
return coin < peeRatio ? Operation.PEE : Operation.POOP;
}
}
... and the demo driver is:
package com.github.coderodde.simulation.toiletseat;
import java.util.Random;
public final class Demo {
private static final int QUEUE_LENGTH = 1000;
private static final double FEMALE_RATIO = 0.55;
private static final double PEE_RATIO = 0.9;
public static void main(String[] args) {
long seed = System.currentTimeMillis();
System.out.println("<<< Seed = " + seed + " >>>");
Random random1 = new Random(seed);
Random random2 = new Random(seed);
ToiletSeatSimulator simulator1 =
new ToiletSeatSimulator(
QUEUE_LENGTH,
FEMALE_RATIO,
PEE_RATIO,
false,
random1);
System.out.println(
"Number of seat moves when changing seat position "
+ "on demand: "
+ simulator1.simulate());
ToiletSeatSimulator simulator2 =
new ToiletSeatSimulator(
QUEUE_LENGTH,
FEMALE_RATIO,
PEE_RATIO,
true,
random2);
System.out.println(
"Number of seat moves when changing seat position back to "
+ "closed: "
+ simulator2.simulate());
}
}
Critique request
Now, what do you think? Did I improve anything?
femaileProportion
. Or is a femaile some kind of email by a female? \$\endgroup\$