# FizzBuzz vs. FortRan

In keeping with using FizzBuzz as an introduction to a language, I present FizzBuzz with a Fortran95 twist:

For multiples of 3, print Fort, and for 5's multiples print Ran. For multiples of both, print FortRan.

Looking especially for style and common practice criticisms. A hint on how to left-justify the values in a standard way would be appreciated too.

The following code is presented in Ideone too:

program fizzbuzz
implicit none
integer ::i

! Loop through integers 1 through 100
! Multiples of 3 print Fort
! Multiples of 5 print Ran
! Multiples of both print FortRan
! 15 is the lowest common multiple of 3, and 5
!    and thus is a shortcut to FortRan

do i=1,100
if (MODULO(i, 15) == 0) then
write (*,'(A8)') 'FortRan'
else if (MODULO(i, 3) == 0) then
write (*,'(A8)') 'Fort'
else if (MODULO(i, 5) == 0) then
write (*,'(A8)') 'Ran'
else
write (*,'(I8)') i
end if
end do

end program fizzbuzz


I find MODULO() to be jarring, when everything else is written in lowercase. Be consistent.

To left-justify strings in the output, write it using a * format. Since you want to write to standard output, you can simplify it by using print instead.

To left-justify numbers in the output, first convert it to a string, then strip leading spaces.

program fizzbuzz
implicit none
integer ::i
character(len=8) :: str

! Loop through integers 1 through 100
! Multiples of 3 print Fort
! Multiples of 5 print Ran
! Multiples of both print FortRan
! 15 is the lowest common multiple of 3, and 5
!    and thus is a shortcut to FortRan

do i=1,100
if (modulo(i, 15) == 0) then
print *, 'FortRan'
else if (modulo(i, 3) == 0) then
print *, 'Fort'
else if (modulo(i, 5) == 0) then
print *, 'Ran'
else
write (str, '(i8)') i
print *, str
end if
end do

end program fizzbuzz

• You can also format the number to just print as many digits as needed by using the i0 formatting string. I don't think print simplifies the output statements. – haraldkl Oct 12 '14 at 0:30

As far as I know, there's nothing substantial to improve.

It's clear, and the program is of trivial size. So any ideas about future extensibility are irrelevant.

Nitpicks:

100 is a magic number explained only by a comment, use fizzBuzzLimit or whatever the case convention for fortran is.

The write function looks weird (Disclaimer: I am not a fortran programmer), maybe wrap it in a helper function (do you even have those in fortran?) so your code reads cleaner.

There is little to criticize. As I commented above, you can also left adjust integers by the i0 format descriptor. I would also intend the main program.

As Fortran actually stands for Formula Translator, I think it would be more appealing to use a split into For and Tran. If you use Trans, you then would even replace the numbers by letters of the numbers values. I also use Doxygen for documentation of Fortran code, and think its syntax is rather unobtrusive. Thus, it usually does not hurt to use it. Finally it is good practice to put functionality into routines, and routines into modules. Though, this might be a little over the top for such a small example, I think it is illustrative to use it her as well. Therefore, here is my suggestion:

!> A module that implements the FizzBuzz series.
module fizzbuzz_module
use iso_fortran_env, only: output_unit

implicit none

private

public :: write_fizzbuzz

contains

!> Write a series of fizzbuzz to unit.
!!
!! This writes all the numbers from lb to ub to unit, but replaces:
!! - multiples of 3 by For
!! - multiples of 5 by Tran
!! - multiples of both, 5 and 3 by ForTran
subroutine write_fizzbuzz(ub, lb, unit)
!> Upper bound up to which the series is to be written.
integer, intent(in) :: ub

!> Lower bound, where the series should start, defaults to 1.
integer, optional, intent(in) :: lb

!> File unit to write the fizzbuzz series to, defaults to stdout.
!!
!! The file has to be opened as formatted file with sequential access
!! and an allowed action to write.
integer, optional, intent(in) :: unit

integer :: i
integer :: loc_lb
integer :: loc_unit

if (present(lb)) then
loc_lb = lb
else
loc_lb = 1
end if

if (present(unit)) then
loc_unit = unit
else
loc_unit = output_unit
end if

do i=loc_lb,ub
! 15 is the lowest common multiple of 3, and 5
!    and thus is a shortcut to ForTran
if (modulo(i, 15) == 0) then
write (loc_unit,'(A7)') 'ForTran'
else if (modulo(i, 3) == 0) then
write (loc_unit,'(A3)') 'For'
else if (modulo(i, 5) == 0) then
write (loc_unit,'(A4)') 'Tran'
else
write (loc_unit,'(I0)') i
end if
end do

end subroutine write_fizzbuzz

end module fizzbuzz_module

!> Small program to illustrate and test the fizzbuzz module.
program test_fizzbuzz
use fizzbuzz_module, only: write_fizzbuzz

implicit none

! Write a fizzbuzz series from 1 to 100 to stdout:
call write_fizzbuzz(ub=100)

! Write the next 100 entries of the fizzbuzz series to stdout:
call write_fizzbuzz(lb=101, ub=200)

end program test_fizzbuzz


By using the private statement in the module, you do not export the output_unit to the using program units, but limit the parts that should be visible to those, you explicitly declare as public. The only clause in the use statement also restricts, what you import from the module, but I use it mainly to indicate, where what is coming from.