<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">// Project 5. Question 3. Solution
// Cafeteria cleanup simulation (with arrays)
// Date: 25 March 2001
// Author: Rimon Barr

public class Simulation {
  // input stream
  private static TokenReader in=new TokenReader(System.in);

  public static void main(String[] args) {
    // read belt length from user
    System.out.print("Please enter belt length &gt;1: [4]");
    int length=in.readInt();
    if(length&lt;=0)
      length=4;
    // run simulation
    Belt b=new Belt(length);
    int run=1;
    int total=0;
    while(!b.isJammed()) {
      System.out.println("Current run: "+run++);
      b.shift();
      System.out.println("Old contents: "+b);
      total+=b.process();
      System.out.println("New contents: "+b);
      System.out.println("Total items taken, so far: "+total);
    }
    System.out.println("The workers are overloaded; belt jammed!");
    System.out.println("Final belt: "+b);
  }
}

class Belt {
  // workers and trays
  private Tray[] trays;
  private Worker[] workers;

  // create new belt of n spots
  public Belt(int n) {
    trays=new Tray[n];
    workers=new Worker[n];
    for(int i=0; i&lt;n; i++) {
      trays[i]=new Tray(Tray.MIN);
      workers[i]=new Worker(i+1, i+1==n);
    }
  }

  // workers process trays; return items processed
  public int process() {
    int total=0;
    for(int i=0; i&lt;workers.length; i++)
      total+=workers[i].process(trays[i]);
    return total;
  }

  // shift all trays, and push new one
  public void shift() {
    for(int i=trays.length-1; i&gt;0; i--)
      trays[i]=trays[i-1];
    trays[0]=new Tray();
  }

  // determine whether belt is jammed / last tray not empty
  public boolean isJammed() {
    return !trays[trays.length-1].isEmpty();
  }

  // string representation of belt
  public String toString() {
    String s="";
    for(int i=0; i&lt;trays.length; i++)
      s+=trays[i].getItems()+" ";
    return s;
  }
}

class Worker {
  // capacity limits, initial efficiency limits, effiency loss
  public static final int MIN_ITEM=2, MAX_ITEM=6;
  public static final double MIN_EFF=0.85, MAX_EFF=1.0;
  public static final double EFF_LOSS=0.95;

  // worker information
  private double eff;     // efficiency
  private int pos;        // position
  private boolean isLast; // sitting at end of belt?

  // construct worker
  public Worker(int pos, boolean last) {
    this.pos=pos;
    eff=Math.random()*(MAX_EFF-MIN_EFF+1)+MIN_EFF;
  }

  // process tray, return number of items removed
  public int process(Tray t) {
    double items=(Math.random()*(MIN_ITEM-MIN_ITEM+1)+MIN_ITEM)*eff;
    int skipFactor=(int)(Math.random()+0.5);
    if(!isLast)
      items-=items/(pos+1)*skipFactor;
    eff*=EFF_LOSS;
    return t.remove((int)items);
  }
}

class Tray {
  public static final int MIN=0, MAX=5;  // capacity limits

  private int items;  // tray capacity

  // construct tray with random number of items
  public Tray() {
    items=(int)(Math.random()*(MAX-MIN+1)+MIN);
  }

  // construct tray with given number of items
  public Tray(int i) {
    items=i;
    if(items&gt;MAX) items=MAX;
    if(items&lt;MIN) items=MIN;
  }

  // return number of items on tray
  public int getItems() { return items; }

  // determine if tray is empty
  public boolean isEmpty() { return items==0; }

  // try remove i items; return number of items actually removed
  public int remove(int i) {
    if(i&gt;items) i=items;
    items-=i;
    return i;
  }
}
</pre></body></html>