I have this task that produces pancake and users can also eat it at the same time. The condition is that it's only 12 pancake that can be produced within 30 seconds. The problem I am having is that as the pancake are being produced, users are eating it as expected but when it produces the last pancake (i.e the 12th one), it terminates without the user eating it, leaving 1 pancake wasted. My final output is thus:
Total number of cake produced is 12
Total number of cake eaten is 11
Total number of pancake remained is 1
public class PanCakeTask {
int consumedPancake;
int availablePancake;
int totalPancakeProduced;
List<String> usersList = new ArrayList<>();
void producePancake(HashMap<String,Integer>users){
consumedPancake =0;
availablePancake = 0;
totalPancakeProduced = 0;
if ( totalPancakeProduced <12) {
for (String user: users.keySet()){
consumedPancake +=users.get(user);
}
//only continue with the production of pancakes if the number of pancakes
//produced has not exceeded the quota that was given (i.e 12)
System.out.println("Pancake produced");
//increment the number of pancakes available
availablePancake +=1;
totalPancakeProduced = consumedPancake + availablePancake;
eatPancake(users);
}
}
void eatPancake(HashMap<String,Integer>users){
if (usersList.size()>=1){
System.out.println("The list is "+usersList);
//first pick the user at random
Collections.shuffle(usersList)
int numberEaten = users.get(usersList.get(0));
//get the user that is on index zero after the list has been shuffled
//then check how many pancake that the picked user has eaten
//because each user is expected to eat a maximum of 5 pancake
if (numberEaten >=5){
//This means that this user has exhausted his/her quota so he/she cannot
//be allowed to eat again
//In this case, the eatPancake method is called again to randomly pick another user
//I am thinking of removing the user from the list here so that he/she cannot be picked again
usersList.remove(0);
eatPancake(users);
}else {
//Meaning that the user still has some quota left for him/her to eat
//In this other condition, it will check if there is an available pancake produced
if (availablePancake >=1){
//user will now eat the pancake
//then increment the number of pancake eaten by that user
// and decrement the number of pancakes available
int newCount = numberEaten + 1;
availablePancake -=1;
//finally update the user that just eaten the pancake
users.put(usersList.get(0),newCount);
}
}
}
}
public void performTask(){
//Hashmap is used to store the users because of key-value pairs
HashMap <String,Integer> users = new HashMap<>();
users.put("user1",0);
users.put("user2",0);
users.put("user3",0);
usersList.addAll(users.keySet());
System.out.println(users);
System.out.println(usersList);
//This task can only be executed in 20 seconds
Instant stop = Instant.now().plusSeconds(20);
System.out.println("The starting time is "+Instant.now());
while (stop.isAfter(Instant.now())){
//only continue the process if it has not exceeded 20 seconds
if (totalPancakeProduced <12){
producePancake(users);
}else {
break;
}
}
int available = totalPancakeProduced - consumedPancake;
int numbersLeftToMeetTheDemand = totalPancakeProduced - 15;
System.out.println("The ending time is "+Instant.now());
System.out.println("Total number of cake produced is "+totalPancakeProduced);
System.out.println("Total number of cake eaten is "+consumedPancake);
System.out.println("Total number of pancake remained is "+available);
}
You are updating consumedPancake
only within the producePancake
method.
This will be an issue when your loop reaches its last iteration. Because, producePancake
will calculate consumedPancake
based on the users
map. After that, eatPancake
is called, which updates the map. This will lead in wrong number of consumed pancakes because consumedPancake
isn't updated again after eatPancake
in the last iteration.
To fix this, instead of modifying consumedPancake
in the producePancake
method, increment it in the eatPancake
method after a pancake is eaten.
Like this:
void eatPancake(HashMap<String,Integer>users){
if (usersList.size()>=1){
System.out.println("The list is "+usersList);
//first pick the user at random
Collections.shuffle(usersList)
int numberEaten = users.get(usersList.get(0));
//get the user that is on index zero after the list has been shuffled
//then check how many pancake that the picked user has eaten
//because each user is expected to eat a maximum of 5 pancake
if (numberEaten >=5){
//This means that this user has exhausted his/her quota so he/she cannot
//be allowed to eat again
//In this case, the eatPancake method is called again to randomly pick another user
//I am thinking of removing the user from the list here so that he/she cannot be picked again
usersList.remove(0);
eatPancake(users);
}else {
//Meaning that the user still has some quota left for him/her to eat
//In this other condition, it will check if there is an available pancake produced
if (availablePancake >=1){
//user will now eat the pancake
//then increment the number of pancake eaten by that user
// and decrement the number of pancakes available
int newCount = numberEaten + 1;
availablePancake -=1;
//finally update the user that just eaten the pancake
users.put(usersList.get(0),newCount);
//here
consumedPancake++;
}
}
}
}
amd remove from producePancake:
void producePancake(HashMap<String,Integer>users){
//consumedPancake =0;
availablePancake = 0;
totalPancakeProduced = 0;
if ( totalPancakeProduced <12) {
/*
for (String user: users.keySet()){
consumedPancake +=users.get(user);
}
*/
//only continue with the production of pancakes if the number of pancakes
//produced has not exceeded the quota that was given (i.e 12)
System.out.println("Pancake produced");
//increment the number of pancakes available
availablePancake +=1;
totalPancakeProduced = consumedPancake + availablePancake;
eatPancake(users);
}
}
Also, there are some redundant parts in your code, but that doesn't seem to be the cause of the problem, so ignored them.