I’m at a beginner level in FORTRAN. Recently, I tried designing a simple program to calculate permutations and combinations. It will have a “menu” for the user to choose an option to proceed…
!/*-------MAIN PROGRAM STARTS-------*/
!PURPOSE: TO CALCULATE COMBINATIONS AND PERMUTATIONS
PROGRAM COMBINATION_PERMUTATION
IMPLICIT NONE
!DECLARATION OF VARIABLES
REAL N, K, FACT, COMBINATION, PERMUTATION
INTEGER CHOICE
!CHOICE MENU
CALL MENU
!USER INPUT OF CHOICE
READ(*,*) CHOICE
!EXECUTION OF CODE BASED ON USER'S CHOICE
SELECT CASE(CHOICE)
CASE(1)
!CALLS SUBROUTINE FOR COMBINATION
CALL COMBINATION_CALC (N, K, FACT, COMBINATION)
CASE(2)
!CALLS SUBROUTINE FOR PERMUTATION
CALL PERMUTATION_CALC (N, K, FACT, PERMUTATION)
CASE(3)
!EXITS THE PROGRAM
STOP
CASE DEFAULT
!INVALID CHOICE LEADS TO MENU BACK
WRITE(*,*) 'INVALID CHOICE! PLEASE CHOOSE AN OPTION TO CONTINUE'
CALL MENU
END SELECT
END PROGRAM COMBINATION_PERMUTATION
!/*-------MAIN PROGRAM ENDS-------*/
!/*-------SUB PROGRAMS START-------*/
!FUNCTION FOR FACTORIAL
FUNCTION FACT(N)
IMPLICIT NONE
REAL FACT, N
INTEGER P, I
P=1
DO I=1, N
P=P*I
END DO
FACT=P
RETURN
END FUNCTION
!SUBROUTINE FOR MENU
SUBROUTINE MENU
IMPLICIT NONE
WRITE(*,*) ' CHOOSE AN OPTION TO CONTINUE.. '
WRITE(*,*) ' 1. COMBINATION '
WRITE(*,*) ' 2. PERMUTATION '
WRITE(*,*) ' 3. EXIT PROGRAM '
RETURN
END SUBROUTINE MENU
!SUBROUTINE FOR COMBINATION
SUBROUTINE COMBINATION_CALC (N, K, FACT, COMBINATION)
IMPLICIT NONE
REAL N, K, FACT, COMBINATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
2 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 2
ELSE IF (K>N)THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 2
ELSE
END IF
COMBINATION=FACT(N)/(FACT(N-K)*FACT(N))
WRITE(*,*) ' HENCE, THERE ARE ', COMBINATION, ' WAYS TO ARRANGE. '
CALL MENU
RETURN
END SUBROUTINE COMBINATION_CALC
!SUBROUTINE FOR PERMUTATION
SUBROUTINE PERMUTATION_CALC (N, K, FACT, PERMUTATION)
IMPLICIT NONE
REAL N, K, FACT, PERMUTATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
3 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 3
ELSE IF (K>N) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 3
ELSE
END IF
PERMUTATION=FACT(N)/FACT(N-K)
WRITE(*,*) ' HENCE THERE ARE', PERMUTATION,' WAYS TO ARRANGE. '
CALL MENU
RETURN
END SUBROUTINE PERMUTATION_CALC
!/*-------SUB PROGRAMS END-------*/
And I’m getting run-time error whenever I enter input 1 or 2 to select a case to proceed….
The error shows as follows in a pop-up window:-
RUN TIME ERROR
Attempt to call a routine with argument number three as real(kind=1) when a procedure was required.
COMBINATION_CALC- in file combinationpermutation.for at line 62[+0068]
main- in file combinationpermutation.for at line 23 [+00e2]
As far as I know, the argument number three in COMBINATION_CALC is “FACT” which is function to calculate factorial. I am not able to understand the error. Kindly guide me. Thanks in advance..
UPDATE
I’ve fixed the RUN-TIME ERROR using the fix given by yosukesabai… my program is now complete..but, INTEGER OVERFLOW is a new problem for me. I’ve changed REAL declaration to INTEGER(KIND=4).. When the N value and K value are more than 12… the resulting answer for combination and permutation will be large… May I know how to fix this?
Here is the new code for my program…
!/*-------MAIN PROGRAM STARTS-------*/
!PURPOSE: TO CALCULATE COMBINATIONS AND PERMUTATIONS
!CREATED BY: RETHNARAJ RAMBABU
!DATE: 28/10/2011
PROGRAM COMBINATION_PERMUTATION
IMPLICIT NONE
!DECLARATION OF VARIABLES
INTEGER CHOICE, N, K
INTEGER(KIND=4) COMBINATION, PERMUTATION
INTEGER, external :: FACT
!CHOICE MENU
1 WRITE(*,*) ' CHOOSE AN OPTION TO CONTINUE.. '
WRITE(*,*) ' 1. COMBINATION '
WRITE(*,*) ' 2. PERMUTATION '
WRITE(*,*) ' 3. EXIT PROGRAM '
!USER INPUT OF CHOICE
READ(*,*) CHOICE
!EXECUTION OF CODE BASED ON USER'S CHOICE
SELECT CASE(CHOICE)
CASE(1)
!CALLS SUBROUTINE FOR COMBINATION
CALL COMBINATION_CALC (N, K, FACT, COMBINATION)
GO TO 1
CASE(2)
!CALLS SUBROUTINE FOR PERMUTATION
CALL PERMUTATION_CALC (N, K, FACT, PERMUTATION)
GO TO 1
CASE(3)
!EXITS THE PROGRAM
STOP
CASE DEFAULT
!INVALID CHOICE LEADS TO MENU BACK
WRITE(*,*) 'INVALID CHOICE! PLEASE CHOOSE AN OPTION TO CONTINUE'
GO TO 1
END SELECT
END PROGRAM COMBINATION_PERMUTATION
!/*-------MAIN PROGRAM ENDS-------*/
!/*-------SUB PROGRAMS START-------*/
!FUNCTION FOR FACTORIAL
FUNCTION FACT(N)
IMPLICIT NONE
INTEGER N, P, I, FACT
P=1
DO I=1, N
P=P*I
END DO
FACT=P
RETURN
END FUNCTION
!SUBROUTINE FOR COMBINATION
SUBROUTINE COMBINATION_CALC (N, K, FACT, COMBINATION)
IMPLICIT NONE
INTEGER N, K, FACT
INTEGER(KIND=4) COMBINATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
2 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 2
ELSE IF (K>N)THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 2
ELSE
END IF
COMBINATION=FACT(N)/(FACT(N-K)*FACT(K))
WRITE(*,*) ' HENCE, THERE ARE ', COMBINATION, ' WAYS TO ARRANGE. '
RETURN
END SUBROUTINE COMBINATION_CALC
!SUBROUTINE FOR PERMUTATION
SUBROUTINE PERMUTATION_CALC (N, K, FACT, PERMUTATION)
IMPLICIT NONE
INTEGER N, K, FACT
INTEGER(KIND=4)PERMUTATION
WRITE(*,*) ' WHAT IS THE VALUE OF N? '
READ(*,*) N
3 WRITE(*,*) ' WHAT IS THE VALUE OF K? '
READ(*,*) K
IF (K<0) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE MORE THAN 0! '
GO TO 3
ELSE IF (K>N) THEN
WRITE(*,*) ' ERROR! VALUE OF K SHOULD BE LESS THAN N! '
GO TO 3
ELSE
END IF
PERMUTATION=FACT(N)/FACT(N-K)
WRITE(*,*) ' HENCE THERE ARE', PERMUTATION,' WAYS TO ARRANGE. '
RETURN
END SUBROUTINE PERMUTATION_CALC
!/*-------SUB PROGRAMS END-------*/
Near the top of your code,
Here you said FACT is real, so fortran assumes that it is a real variable. But you meant this to be reference to function you defined in the same file. So revise like
external is fortran way of saying that it is a function you defnined somewhere outside of a program block (program, subroutine or function)
(ignore below here if you dont care)
I notice that there is no point of passing function reference. so you may want to stop passing function around, and just call that straight from subroutine combination_calc. in that case, n,k,combination are the three arguments for subroutine, and inside combination_calc you will have
real, external :: fact.