! pascalstriangle.f90

! © Copyright 2003-4 Dauger Research, Inc. 
    
! Our lawyers made us say this: 
! DISCLAIMER: We provide the following on an "AS IS" basis. Use it at your own risk.  

      module pascallib
      contains 
       
! Routines performing elemental work. 
      subroutine addright(inputArray, inputSize)
      implicit none
      integer, dimension(:) :: inputArray
      integer :: inputSize, i 
      if (size(inputArray).gt.1) then
		do i = inputSize, 1, -1 
			inputArray(i+1)=inputArray(i+1)+inputArray(i)
        end do
      end if
      end subroutine
    
      subroutine addleft(inputArray, inputSize)
      implicit none
      integer, dimension(:) :: inputArray
      integer :: inputSize, i 

      if ((size(inputArray).gt.1)) then
        do i=1, inputSize
			inputArray(i)=inputArray(i)+inputArray(i+1)
        end do
      end if
      end subroutine

      subroutine iterationloop(theArray, arraySize, lastIteration, verbose)
      implicit none
      integer, dimension(:) :: theArray
      integer :: arraySize, lastIteration, verbose, index, i
	
      if (arraySize.gt.0) then
		
! loop over indicies 
		do index=0, lastIteration-1 
! call the left or right routine for each index, reusing array 
          if (iand(1,index)/=0) then
				call addleft(theArray, arraySize)
          else 
				call addright(theArray, arraySize)
          end if
			
          if (verbose/=0) then
            do i=1,arraySize
              if (iand(1,verbose)/=0) then
                write(*, '(I6)', advance="no") theArray(i)
              else 
                if (iand(1,theArray(i))/=0) then
                  write(*, '(A)', advance="no") '*'
                else
                  write(*, '(A)', advance="no") ' '
                end if
              end if
            end do
            print *," " 
          end if
        end do
 		
      end if
      
      end subroutine
	
! BinomalExponent specifies how far to propagate 

      subroutine computeloop(theArray, binomialExponent)
      implicit none
      integer, dimension(:) :: theArray
      integer :: binomialExponent
! local copies of the data to be output 
      integer :: arraySize, i
      integer, dimension(binomialExponent+1) :: myArray
	  
	  arraySize = binomialExponent + 1
	  
! allocate an array to hold all the results 
	
      if (arraySize.gt.1) then
		
	! clear the array 
        do i=1, arraySize
          myArray(i)=0 
        end do
		
	! seed the array 
        myArray((binomialExponent/2)+1) = 1 
		
	! propagate 
        call iterationloop(myArray, arraySize, binomialExponent, 2)
      end if
	
! return the array 
	  theArray=myArray
	
      end subroutine
    	
      end module
	
      program pascal
      use pascallib
      implicit none
! BinomialExponent specifies how far to propagate 
      integer, parameter :: BinomialExponent = 30
! main copies of the sum and the array 
      integer, dimension(BinomialExponent) :: theArray
      integer :: ios
	
      print *,"Beginning computation...\n"
	
      call computeloop(theArray, BinomialExponent)
	
		
! save the array into a data file 
        open(unit = 2, file = "output", status = "replace", iostat = ios, form = "unformatted") 
        if (ios .eq. 0) then
          print *, "writing array...\n"
	
          write(unit = 2) theArray
			
          endfile 2 
        end if
		
      write( *, '(I16)', advance="no") theArray
      print *, " "
	
      stop 
      end program