PROGRAM Change_Dispenser
!-----------------------------------------------------------------------
! This is a driver program to test subroutine Dispense.  Variables used:
!   ItemCost    : cost of item
!   AmountPaid  : amount paid by customer
!   NumDollars  : number of dollars,
!   NumQuarters :    quarters,
!   NumDimes    :    dimes,
!   NumNickels  :    nickels,
!   NumPennies  :    pennies   to be returned in change
!   Response    : user response to More data? query
!
! Input : ItemCost and AmountPaid
! Output: Change in dollars, quarters, dimes, nickels, and pennies
!-----------------------------------------------------------------------

  IMPLICIT NONE
  REAL :: ItemCost, AmountPaid
  INTEGER :: NumDollars, NumQuarters, NumDimes, NumNickels, NumPennies
  CHARACTER(1) :: Response

  PRINT *, "This program tests a change-dispensing subroutine."
  PRINT *

  ! Do the following until user indicates no more data
  DO
     WRITE (*, '(1X, A)', ADVANCE = "NO") &
           "Enter cost of item and amount paid by customer: "
     READ *, ItemCost, AmountPaid
     CALL Dispense(ItemCost, AmountPaid, &
           NumDollars, NumQuarters, NumDimes, NumNickels, NumPennies)
     PRINT '(1X, A / 6(1X, I3, 1X, A /))', &
              "The change from this purchase is:", &
              NumDollars, "Dollars", NumQuarters, "quarters", &
              NumDimes, "Dimes", NumNickels, "Nickels", &
              NumPennies, "Pennies"
     WRITE (*, '(/ 1X, A)', ADVANCE = "NO") "More data (Y or N)? "
     READ *, Response
     IF (Response /= "Y") EXIT
  END DO

CONTAINS

  !Dispense---------------------------------------------------------------
  ! Subroutine to compute the dollars, quarters, dimes, nickels, and
  ! pennies in change given the amount of a purchase and the amount paid
  ! by the customer.  Local variable used:
  !   Change : the amount to be returned in change (in cents)
  !
  ! Accepts: Amount of Purchase and Payment made by customer
  ! Returns: Dollars, Quarters, Dimes, Nickels, Pennies, the number of
  !          dollars, quarters, dimes, nickels, and pennies to be
  !          returned in change.
  !-----------------------------------------------------------------------
  
    SUBROUTINE Dispense(Purchase, Payment, &
                        Dollars, Quarters, Dimes, Nickels, Pennies)
  
    IMPLICIT NONE
    REAL, INTENT(IN) :: Purchase, Payment
    INTEGER, INTENT(OUT) :: Dollars, Quarters, Dimes, Nickels, Pennies
    INTEGER :: Change
  
    ! Calculate amount of change in cents
    Change = ANINT(100 * (Payment - Purchase))
  
    IF (Change > 0) THEN
       ! Compute number of dollars
       Dollars = Change / 100
       Change = MOD(Change, 100)
  
       ! Compute number of quarters
       Quarters = Change / 25
       Change = MOD(Change, 25)
  
       ! Compute number of dimes
       Dimes = Change / 10
       Change = MOD(Change, 10)
  
       ! Compute number of nickels and pennies
       Nickels = Change / 5
       Pennies = MOD(Change, 5)
  
    ELSE
       ! Insufficient payment
       PRINT *, "*** Payment too small by", -Change, "cents ***"
       Dollars = 0
       Quarters = 0
       Dimes = 0
       Nickels = 0
       Pennies = 0
  
    END IF
  
  END SUBROUTINE Dispense

END PROGRAM Change_Dispenser
