function deli ( lambda, mu, clerk_count )

%*****************************************************************************80
%
%% deli() simulates the operation of a deli.
%
%  Discussion:
%
%    A deli is open for 36,000 seconds.
%    There are 1 or 2 clerks.
%    Customers arrive at random.
%    The amount of time it takes to service a customer is random.
%    Customers are served in order.
%    A clerk serves one customer at a time.
%    Newly arrived customers wait in a queue if no clerk is available.
%    What is the average and maximal times spent per customer?
%    What is the average and maximal queue length?
%    What percentage of time are the clerks idle?
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    28 January 2018
%
%  Author:
%
%    Paul Nahin
%
%  Reference:
%
%    Paul Nahin,
%    Digital Dice: Computational Solutions to Practical Probability Problems,
%    Princeton, 2008,
%    ISBN: 978-0-691-15821-1.
%
%  Input:
%
%    real LAMBDA, the average customer arrival rate per hour.
%
%    real MU, the average customer service rate per hour.
%
%    integer CLERK_COUNT, is 1 or 2, the number of clerks.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, 'deli():\n' );
  fprintf ( 1, '  A deli is open for 36,000 seconds.\n' );
  fprintf ( 1, '  There are 1 or 2 clerks.\n' );
  fprintf ( 1, '  Customers arrive at random.\n' );
  fprintf ( 1, '  The amount of time it takes to service a customer is random.\n' );
  fprintf ( 1, '  Customers are served in order.\n' );
  fprintf ( 1, '  A clerk serves one customer at a time.\n' );
  fprintf ( 1, '  Newly arrived customers wait in a queue if no clerk is available.\n' );
  fprintf ( 1, '  What is the average and maximal times spent per customer?\n' );
  fprintf ( 1, '  What is the average and maximal queue length?\n' );
  fprintf ( 1, '  What percentage of time are the clerks idle?\n' );

  clock = 0;
  clerk_busy1 = 0;
  clerk_busy2 = 0;
  queue_length = 0;
  service_time_remaining1 = 0;
  service_time_remaining2 = 0;
  queue = zeros(2,200);
  clerk_idle_time1 = 0;
  clerk_idle_time2 = 0;
  close_deli = ceil ( lambda * 30 );
  customer_arrival_time(1) = ceil ( - 3600 * log ( rand ( ) ) / lambda );

  for i = 2 : close_deli
    customer_arrival_time(i) = customer_arrival_time(i-1) ...
      + ceil ( - 3600 * log ( rand ( ) ) / lambda );
  end

  for i = 1 : close_deli
    customer_service_time(i) = ceil ( - 3600 * log ( rand ( ) ) / mu );
  end

  total_time = 0;
  max_total_time = 0;
  total_queue_length = 0;
  max_queue_length = 0;
  new_customer = 1;

  if ( clerk_count == 1 )
    clerk_busy2 = 1;
    service_time_remaining2 = 10 ^ 10;
  end

  while ( clock < 36000 )

    if ( service_time_remaining1 > 0 )
      service_time_remaining1 = service_time_remaining1 - 1;
    end

    if ( service_time_remaining2 > 0 )
      service_time_remaining2 = service_time_remaining2 - 1;
    end

    if ( ( clerk_busy1 == 0 || clerk_busy2 == 0 ) && ( queue_length > 0 ) )
      if ( clerk_busy1 == 0 )
        clerk_busy1 = 1;
        service_time_remaining1 = queue(2,1);
      else
        clerk_busy2 = 1;
        service_time_remaining2 = queue(2,1);
      end

      total_time = total_time + queue(1,1) + queue(2,1);

      if ( queue(1,1) + queue(2,1) > max_total_time )
        max_total_time = queue(1,1) + queue(2,1);
      end

      for i = 1 : queue_length - 1
        queue(1,i) = queue(1,i+1);
        queue(2,i) = queue(2,i+1);
      end
      queue_length = queue_length - 1;

    end

    if ( ( clock == customer_arrival_time(new_customer) ) && ...
      ( clerk_busy1 == 0 || clerk_busy2 == 0 ) )

      if ( clerk_busy1 == 0 )
        clerk_busy1 = 1;
        service_time_remaining1 = customer_service_time(new_customer);
      else
        clerk_busy2 = 1;
        service_time_remaining2 = customer_service_time(new_customer);
      end

      total_time = total_time + customer_service_time(new_customer);

      if ( customer_service_time(new_customer) > max_total_time )
        max_total_time = customer_service_time(new_customer);
      end

      new_customer = new_customer + 1;

    elseif ( ( clock == customer_arrival_time(new_customer) ) && ...
      ( clerk_busy1 == 1 && clerk_busy2 == 1 ) )

      queue_length = queue_length + 1;
      queue(1,queue_length) = 1;
      queue(2,queue_length) = customer_service_time(new_customer);
      new_customer = new_customer + 1;

    end

    if ( clerk_busy1 == 0 )
      clerk_idle_time1 = clerk_idle_time1 + 1;
    end

    if ( clerk_busy2 == 0 )
      clerk_idle_time2 = clerk_idle_time2 + 1;
    end

    for ( i = 1 : queue_length )
      queue(1,i) = queue(1,i) + 1;
    end

    if ( service_time_remaining1 == 0 )
      clerk_busy1 = 0;
    end

    if ( service_time_remaining2 == 0 )
      clerk_busy2 = 0;
    end

    total_queue_length = total_queue_length + queue_length;

    if ( queue_length > max_queue_length )
      max_queue_length = queue_length;
    end

    clock = clock + 1;

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, '  Average total time at deli %g\n', total_time / ( new_customer - 1 - queue_length ) );
  fprintf ( 1, '  Maximum time at deli       %g\n', max_total_time );
  fprintf ( 1, '  Average queue length       %g\n', total_queue_length / clock );
  fprintf ( 1, '  Maximum queue length       %g\n', max_queue_length );
  fprintf ( 1, '  Percent idle time clerk1   %g\n', 100 * clerk_idle_time1 / clock );
  fprintf ( 1, '  Percent idle time clerk2   %g\n', 100 * clerk_idle_time2 / clock );

  return
end

