      PROGRAM SORTER
************************************************************************
* This program reads and counts a list of labor costs, sorts them in   *
* ascending order, and finds the median cost.  For more costs, change  *
* the value of the parameter LIMIT.  Identifiers used are:             *
*     LIMIT   :  parameter representing maximum # of costs             *
*     COST    :  list of labor costs (in millions)                     *
*     N       :  number of labor costs                                 *
*                                                                      *
* Input:  Elements of COST -- using subroutine RDCOST                  *
* Output: Sorted elements of COST -- using subroutine OUTPUT           *
************************************************************************

      INTEGER LIMIT
      PARAMETER (LIMIT = 100)
      INTEGER COST(LIMIT), N

      CALL RDCOST(COST, LIMIT, N)
      CALL SORT(COST, LIMIT, N)
      CALL OUTPUT(COST, LIMIT, N)

      END


**RDCOST****************************************************************
* Subroutine to read a list of up to LIMIT costs, store them in array  *
* COST, return this list and a count N of the number of values read.   *
* Local variables:                                                     *
*     INDATA  : data value read (an actual cost or end-of-data signal) *
*                                                                      *
* Accepts:  Array COST (undefined) and integer LIMIT                   *
* Input:    Elements of COST                                           *
* Returns:  Array COST (modified) and integer N                        *
************************************************************************

      SUBROUTINE RDCOST(COST, LIMIT, N)

      INTEGER LIMIT, COST(LIMIT), N, INDATA

      PRINT *, 'ENTER LABOR COSTS IN MILLIONS (0 OR NEGATIVE TO STOP).'
      N = 0
      READ *, INDATA

* While there is another data value, count it, store it in
* the next location of array COST, and read another value.

10    IF (INDATA .GT. 0) THEN
          N = N + 1
          COST(N) = INDATA
          READ *, INDATA
      GO TO 10
      END IF
     
      END

**SORT******************************************************************
* Subroutine to sort ITEM(1), ..., ITEM(N) into ascending order using  *
* the simple selection sort algorithm.  LIM is the upper limit on the  *
* size of the array ITEM.  For descending order change .LT. to .GT. in *
* the logical expression ITEM(I) .LT. SMALL. Local variables used:     *
*      SMALL   : smallest item in current sublist                      *
*      LOCSM   : location of SMALL                                     *
*      I, J    : subscripts                                            *
*                                                                      *
* Accepts:  Array ITEM and integers LIM and N                          *
* Returns:  Array ITEM (modified) with first N elements in ascending   *
*           order                                                      *
************************************************************************

      SUBROUTINE SORT(ITEM, LIM, N)   

      INTEGER LIM, ITEM(LIM), N, I

      DO 20 I = 1, N - 1

*         Find smallest item in sublist ITEM(I), ..., ITEM(N)
          
          SMALL = ITEM(I)
          LOCSM = I
          DO 10 J = I + 1, N
              IF (ITEM(J) .LT. SMALL) THEN
*                  Smaller item found
                   SMALL = ITEM(J)
                   LOCSM = J
              END IF
10        CONTINUE

*         Interchange smallest item with ITEM(I) at
*         beginning of sublist

          ITEM(LOCSM) = ITEM(I)
          ITEM(I) = SMALL

20    CONTINUE
      END

**OUTPUT****************************************************************
* Subroutine to display the sorted list of N COSTs and the median      *
* cost.  LIMIT is the upper limit on the array COST.  Local variables: *
*     I      : subscript                                               *
*                                                                      *
* Accepts:  Array COST and integers LIMIT and N                        *
* Output:   First N elements of COST and the median cost               *
************************************************************************

      SUBROUTINE OUTPUT(COST, LIMIT, N)

      INTEGER LIMIT, COST(LIMIT), N, I

      PRINT 100, 'SORTED LIST', '====== ===='
100   FORMAT(2(/, 1X, A))
      DO 10 I = 1, N
          PRINT 101, COST(I)
101       FORMAT(1X, I6)
10    CONTINUE
      IF (MOD(N,2) .NE. 0) THEN
          PRINT 102, COST((N + 1)/2)
      ELSE
          PRINT 102, (COST(N/2) + COST(N/2 + 1)) / 2.0
      END IF
102   FORMAT(/1X, 'MEDIAN = ', I6, ' MILLION DOLLARS')
      END
