function [ coupon, n_coupon ] = coupon_simulate ( n_type )

%*****************************************************************************80
%
%% coupon_simulate() simulates the coupon collector's problem.
%
%  Discussion:
%
%    The coupon collector needs to collect one of each of N_TYPE
%    coupons.  The collector may draw one coupon on each trial,
%    and takes as many trials as necessary to complete the task.
%    On each trial, the probability of picking any particular type
%    of coupon is always 1 / N_TYPE.
%
%    The most interesting question is, what is the expected number
%    of drawings necessary to complete the collection?
%    how does this number vary as N_TYPE increases?  What is the
%    distribution of the numbers of each type of coupon in a typical
%    collection when it is just completed?
%
%    As N increases, the number of coupons necessary to be
%    collected in order to get a complete set in any simulation
%    strongly tends to the value N_TYPE * LOG ( N_TYPE ).
%
%    If N_TYPE is 1, the simulation ends with a single drawing.
%
%    If N_TYPE is 2, then we may call the coupon taken on the first drawing
%    a "Head", say, and the process then is similar to the question of the
%    length, plus one, of a run of Heads or Tails in coin flipping.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    16 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer N_TYPE, the number of types of coupons.
%
%  Output:
%
%    integer COUPON(N_TYPE), the number of coupons of each type
%    that were collected during the simulation.
%
%    integer N_COUPON, the total number of coupons collected.
%
  max_coupon = 2000;

  coupon(1:n_type) = 0;

  straight = 0;
  n_coupon = 0;
%
%  Draw another coupon.
%
  while ( n_coupon < max_coupon )

    i = randi ( [ 1, n_type ], 1 );
%
%  Increment the number of I coupons.
%
    coupon(i) = coupon(i) + 1;
    n_coupon = n_coupon + 1;
%
%  If I is the next one we needed, increase STRAIGHT by 1.
%
    if ( i == straight + 1 )

      while ( true )

        straight = straight + 1;
%
%  If STRAIGHT = N_TYPE, we have all of them.
%
        if ( n_type <= straight )
          return;
        end
%
%  If the next coupon has not been collected, our straight is over.
%
        if ( coupon(straight+1) <= 0 )
          break;
        end

      end

    end

  end

  fprintf ( 1, '\n' );
  fprintf ( 1, 'coupon_simulate(): Fatal error!\n' );
  fprintf ( 1, '  Maximum number of coupons drawn without success.\n' );

  return
end
