java adding objects to ArrayDeque at random intervals - java

Trying to add objects to a ArrayDeque at random intervals. This is what I have
for (int i = 0; i <= 100; i ++) {
if (window.isEmpty()) {
Customer customer = new Customer(r.nextInt(10)+1);
q.add(customer);
window.beginService();
}
else {
Customer customer = new Customer(r.nextInt(10)+1);
q.add(customer);
window.beginService();
totalCustomers++;
totalServiceTime += window.serviceTime;
totalWaitTime += customer.getArrivalTime();
}
}
The other methods being used are
public boolean isEmpty() {
if (serviceTime == 0) {
return true;
}
else
return false;
}
public void beginService() {
if (isEmpty()) {
serviceTime = r.nextInt(10)+1;
}
else
serviceTime += r.nextInt(10)+1;
}
public Customer(int arrivalTime) {
this.arrivalTime = arrivalTime;
}
public int getArrivalTime() {
return arrivalTime;
}
When I print out my customer count it is equal to my clock time, which should not be as customers are added at random intervals of 1-10. Any ideas?

Are you defining your "clock time" as the value of i? If so, I'm not sure why you would expect it and totalCustomers to be different.
In your for loop, you add a customer regardless of whether or not the windows is empty. After the first time around, the window will never be empty because you are always beginning service which always increments the serviceTime by at least 1.
So after the first iteration of the loop, the else branch of your if will exclusively be executed and totalCustomers will always increment alongside of i.
I think you have bigger logic gaps in your code but you haven't been very clear with how you've framed your question or shown your code. It is unclear how serviceTime is declared or what the code is supposed to be doing. You never seem to take an item off of the queue. If you need more help than this you need to put some more effort into your question.

Related

Is it possible for a method to stop another method from being called if a condition is true?

I've been given an assignment to edit a game and add different elements to it, one was the ability to restore player life when interacting with an object which I have completed.
The next step is to stop this from working when the players life is max (100).
My idea then was to create a method with a condition (and if it is true, stop my life adding method from working / being called.)
Example:
private void checkMaxLife() {
if (playerLife==100) {
//Stop method addLife from working
}
}
Would this be possible and what is the syntax?
EDIT:
This was the fix, added playerLife < 100 to the collision method instead.
private void foodAddLife() {
//Check food collisions
for (int i = 0; i < food.length; ++i) {
if (playerLife < 100 && food[i].getX() == player.getX() && food[i].getY() == player.getY()) {
//We have a collision
++playerLife;
}
}
It seems you don't need checkMaxLife, just use the attribute playerLife in the method addLife
private void addLife() {
if (playerLife < 100) {
playerLife++; // or whatever value
}
}
With 2 methods, you see that one is useless
private boolean isFullLife() {
return playerLife >= 100;
}
private void addLife() {
if (!isFullLife()) {
playerLife++; // or whatever value
}
}
You just return the function when player life is MAX_VALUE.
private void addLife() {
if(playerLife>=100)
return;
// Do Whatever you need to do
}

Adding object to a ArrayList in a correct index using for-loop

I have a method to add a patient to the correct index depending on their priority. However it seems that when I add more than one person, it doesn't get added. I'm not too sure what I'm missing in my add method. My guess is there is something wrong with the if-else statement but I'm not able to pinpoint where the problem is.
public void addPatient(Patient sickPerson)
{
int lim = patients.size();
if (patients.isEmpty()) //if empty
{
patients.add(sickPerson);
}
else //if not empty
{
for (int i = 0; i < lim; i++)
{
if (patients.get(i).compareTo(sickPerson) > 0)
// if the sickperson is more important...
{
patients.add(i, sickPerson);
}
else if (patients.get(i).compareTo(sickPerson) == 0)
// if the sickperson's priority is the same,
{
patients.add(i + 1, sickPerson);
}
else
{
continue;
}
}
}
}
#Test
public void getNumWaitingTest() {
WaitingRoom a = new WaitingRoom();
Patient b = new Patient("name", "bad", 1, 1);
Patient c = new Patient("name2", "bad2", 2, 2);
a.addPatient(b);
a.addPatient(c);
assertEquals(2, a.getNumWaiting());
}
and if I run this test case, I would get 1 for the numWaiting for some reason...
where could I have gone wrong in this code??
After the for cycle you are not adding any patient if they have lower priority than the existing ones.
As soon as you add a patient in the list you should return from the method; if you reach the end of the method it means that the new patient has the lowest priority and you should add him at the end of the list.

The "if" condition in "set" method isn't working

So which floor the lift is on should be able to be read and changed, but only within the allowed range for just that house the lift is installed in. I'm trying to get an "If" condition working looking for a boolean true value from method "validFloor".
Based on my very beginner knowledge of Java, I assume putting an "If" condition in the set-method is a proper attempt?
private int currentFloor = 0;
private int numberOfFloors;
private boolean validFloor = false;
public Elevator(int numberOfFloors) {
this.numberOfFloors = numberOfFloors;
}
//Sets the allowed number of floors (0 to 100)
public void allowedNumberOfFloors() {
if (numberOfFloors < 2) {
numberOfFloors = 2;
} else if (numberOfFloors > 100) {
numberOfFloors = 100;
}
}
//Checks validity of the elevator floor in relation to total floors.
public void validFloor() {
if (currentFloor > numberOfFloors && currentFloor < 0) {
this.validFloor = false;
}
}
//Checks whether the specified floor is in reasonable range.
public void setFloor(int currentFloor) {
if (validFloor) {
this.currentFloor = currentFloor;
}
}
public int getFloor() {
return currentFloor;
}
public String toString() {
return "Number of floors: " + numberOfFloors + "\nCurrent floor: " + currentFloor;
}
For example, if you try to move the lift to floor 74 in a house that only has 5 floors, it should not work. I want the hiss to start at bottom floor 0, hence the 0 value in class variable "currentFloor".
The If condition in the "validFloor" method doesn't seem to be recognized at all. Instead all that matters is the boolean value I put on the class variable validFloor.
You never call the validFloor() method, so the value of validFloor is never changed. Also, you code never sets validFloor to true anywhere, so it wouldn't even matter if you called validFloor(), because it can only set validFloor to false, or leave it at the initial value of false.
The "correct" way to do something like this is:
public boolean isValidFloor(floor) {
// It seems weird to me that 0 is a valid floor. Is that correct?
// If floors are zero-indexed, the top floor should actually be numberOfFloors-1.
return floor >= 0 && floor <= this.numberOfFloors;
}
public void setFloor(int newFloor) {
if (isValidFloor(newFloor)) {
this.currentFloor = newFloor;
}
}
Notice that there's no need to even keep around a validFloor variable. We can just check whether or not a floor is valid every time we need to without saving the result.

Java Min-Heap Implementing Priority Queue - Iteration

I'm trying to use this code to implement a Priority Queue. There are a number of questions regarding this implementation on the site, but given how many different ways you can write code to do essentially the same thing I am still at a loss after looking through a handful of other examples.
There are some missing lines in this code, but I am limited to editing only the four marked lines and so I find myself stuck on one particular aspect. I can't seem to understand how 'quantity' is incremented.
From my understanding main creates a new object of maxSize = 5. Then calls the insertItem method passing the value of 130. This should be placed into the root (I had put queArray[quantity] = item; into the first blank) at which point the insertItem method exits and is then called again with the next value. So at what point is 'quantity' incremented? Maybe I am missing something incredibly simple, or maybe there is another way of solving this that may not be apparent or known to beginners like me?
I would think you would want to increment quantity under the initial if statement, but that doesn't seem to be an option, so as far as I can tell the else statement can never be executed as quantity doesn't change. I know I am incorrect, but I don't know how, some help would be greatly appreciated.
public class Main {
/**
* #param args the command line arguments
*/
// array in sorted order, from max at 0 to min at size-1
private int maxSize;
private long[] queArray;
private int quantity;
public Main(int s) {
maxSize = s;
queArray = new long[maxSize];
quantity = 0;
}
public void insertItem(long item) {
int i;
if (quantity == 0)
__________; // insert at 0
else
{
for (i = quantity - 1; i >= 0; i--) // start at end,
{
if (item > queArray[i]) // if new item larger,
__________; // shift upward
else
// if smaller,
break; // done shifting
}
__________; // insert it
__________;
} // end else (quantity > 0)
}
public boolean PQEmpty(){
return (quantity == 0);
}
public long removeItemPQ(){
return queArray[--quantity];
}
public long peekMin(){
return queArray[quantity - 1];
}
public static void main(String[] args) {
Main thePQ = new Main(5);
thePQ.insertItem(130);
thePQ.insertItem(450);
thePQ.insertItem(110);
thePQ.insertItem(430);
thePQ.insertItem(280);
while (!thePQ.PQEmpty()) {
long item = thePQ.removeItemPQ();
System.out.print(item + " ");
}
System.out.println("");
}
}
It isn't a style I'd recommend, but you could use queArray[quantity++] = item;.

How to start back at beginning of arraylist in a while loop?

I'm trying to solve a puzzle that goes like this: 100 people stand in a circle. The first person kills the person next to him and hands the gun to the next person. Which person is left at the end?
This is what I have so far, but when I run it, it shows an out of bounds exception. I realized that when I write people.remove(i+1), the program runs to the end of the arraylist and has no way to start back at the beginning to continue the pattern. How do I do this?
Thanks for any help!
private void btnEnterActionPerformed(java.awt.event.ActionEvent evt) {
int input = Integer.parseInt(txtInput.getText());
ArrayList <Integer> people = new ArrayList <> ();
for (int i = 0; i < input; i++) {
people.add(i);
}
while (people.size() != 0) {
int i = 1;
people.remove(i+1);
i++;
}
for (int i = 0; i < people.size(); i++) {
lblOutput.setText(" " + people.get(i));
}
The reason you get an out of bound exception is that you check the size to be non-zero, but the call of remove(i+1) with i set to 1 means removing from the third spot in the list, which may not be there. Only the initial element at index zero is guaranteed to be there.
Also note that i++ has no effect, because i is reset back to 1 at the top of the loop's body.
With the condition of people.size() != 0 the only guaranteed thing is that you would be able to remove at index zero. However, this is rather inefficient, because all elements past that index need to be copied. This makes removal an O(n2), which could be slow when the list is really long.
Generally, though, the idiomatic way of managing removals from a list is using ListIterator<T> for removal of zero to a few items, or copying into a separate list and replacing the original list with the new one when you need to remove a significant portion of the list.
As I understand the problem, you need to remove every second person from the list until only one person remains.
The basic problem with your current implementation, is, first, you don't do any range checking (how do you know an element actually exists at i+1) and secondly, you loop until the list is empty, which isn't what you really want.
The basic requirement could use compounding loops, the outer loop checks the size of the list and keeps looping while the size of the List is greater then 1, the second loop processes the list, removing every other person from the list. Note, I don't reset the hasGun flag in the outer loop, this means that on each iteration of the inner loop, the gun continues to pass to the next survivor.
ArrayList<Integer> people = new ArrayList<>();
for (int i = 0; i < 10; i++) {
people.add(i);
}
boolean hasGun = true;
while (people.size() > 1) {
Iterator<Integer> iterator = people.iterator();
while (iterator.hasNext()) {
System.out.print("> " + iterator.next());
if (!hasGun) {
// You get shot...
iterator.remove();
System.out.println(" got shot");
} else {
System.out.println(" shoots");
}
hasGun = !hasGun;
}
}
for (Integer person : people) {
System.out.println(person);
}
This example also makes uses the List's Iterator, this over comes, in part, the issue of the array out of bounds, but you could also use a for-next loop and the hasGun flag as well.
To circulate through your array with indexing, use the remainder operator:
int actual = 0;
while (people.size() != 1) {
people.remove( (actual+1) % people.size() );
actual = (actual+1) % people.size();
}
I just think an ArrayList is not the best data structure for this problem. I find a LinkedList would be more fit. Actually, I found a very easy recursive solution using one. Have a look at this code:
public class Main {
public static int kill(LinkedList<Integer> people) {
assert people.size() > 0;
System.out.println("people: " + people);
if (people.size() < 3)
return people.getFirst();
else {
System.out.println("kill: " + people.remove(1));
people.addLast(people.removeFirst());
return kill(people);
}
}
public static void main(String[] args) {
LinkedList<Integer> people = new LinkedList<>();
for (int i = 0; i <=100; i++) {
people.add(i);
}
int survivor = kill(people);
System.out.println("Last survivor: " + survivor);
}
}
I just remove (kill?) the second member on the list and send the first one back to the end of the list. This process can be repeated until there are 2 people left, in which case you can guess the last survivor will be the first one in the list cause he will kill the second person.
If I had to resolve this problem, I would create my own Person class with a next property pointing to the next person.
Person class:
public class Person {
private int id;
private Person next;
public Person(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
public Person getNext() {
return this.next;
}
public void setNext(Person next) {
this.next = next;
}
public void killNext() {
this.next = this.next.next;
}
}
Once that is in place, it's trivial to setup a circular set of linked persons. The algorithm then simply becomes looping each person by following the next property, killing the next person on each iteration. And the loop exits when the next property points to himself, indicating that there is no one left.
Algorithm:
public static void main(String[] args) {
// Setup 100 persons in a linked circle.
Person startingPerson = new Person(1);
Person currentPerson = startingPerson;
for (int i = 2; i <= 100; i++) {
currentPerson.setNext(new Person(i));
currentPerson = currentPerson.getNext();
}
currentPerson.setNext(startingPerson);
// Loop around until a single person is left.
currentPerson = startingPerson;
while (currentPerson != currentPerson.getNext()) {
currentPerson.killNext();
currentPerson = currentPerson.getNext();
}
System.out.println("Surviving person: " + currentPerson.getId());
}
Output:
Surviving person: 73

Categories

Resources