Reputation: 51
This is the program I am compiling in Fortran. It calculates two different formulas for even and odd numbers and it stops when you get 1 as result. If I choose N = 50
for example, I get all the values displayed in the same line. I would like maximum 40 characters (including numbers and commas) printed per line. I also need to store the last numbers (4,2,1)
, but I don't know how.
That's what I am getting when I compile the program.
50, 25, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1,
That's what I want (40 characters per line):
50, 25, 76, 38, 19, 58, 29, 88, 44, 22,
11, 34, 17, 52, 26, 13, 40, 20, 10, 5,
16, 8, 4, 2, 1,
program numbers
implicit none
integer(kind=4) :: i, n
print*,'Enter the N value'
read*, n
do while (n.ne.1)
if (mod(n,2) .eq.0) then
n = n/2
write(6,'(i0,a)',advance='no') n,','
else if (mod(n,2) .ne.0) then
n = (3*n)+1
write(6,'(i0,a)',advance='no') n,','
else
cycle
end if
end do
end program numbers
Upvotes: 3
Views: 466
Reputation: 1585
Here is a general solution that you can adopt for your code. Given an input string msg
, it prints lines no longer than 40 characters in length (adjust MAX_LINE_LEN
below if necessary). The lines are split only at spaces.
implicit none
character(:), allocatable :: msg
msg = '50, 25, 76, 38, 19, 58, 29, 88, 44, 22, 11, 34, 17, 52, 26, 13, 40, &
&20, 10, 5, 16, 8, 4, 2, 1,'
call print_msg(msg)
contains
recursive subroutine print_msg(msg)
character(*), intent(in) :: msg
integer, parameter :: MAX_LINE_LEN = 40
integer :: length
if (len(msg) <= MAX_LINE_LEN) then
length = len(trim(msg))
else if (index(msg(:MAX_LINE_LEN), ' ') > 0) then
length = index(msg(:MAX_LINE_LEN), ' ', back=.true.)
else
length = MAX_LINE_LEN
end if
write(*, '(*(g0))') msg(:length)
if (len(msg) > MAX_LINE_LEN) then
call print_msg(msg(length+1:))
end if
end subroutine print_msg
end program
The output is
50, 25, 76, 38, 19, 58, 29, 88, 44, 22,
11, 34, 17, 52, 26, 13, 40, 20, 10, 5,
16, 8, 4, 2, 1,
Upvotes: 1
Reputation: 3819
You could tell the compiler break lines after a given number of characters, but that would also break them midnumber. If you want to avoid that, you could just count the number of characters.
Maybe the easiest to do that would be to write to string and to use len_trim
to figure out its length.
For keeping the last three numbers around you could use an array of length three and put a number into index of current iteration modulo 3.
Something like this maybe:
program numbers
implicit none
integer :: i, n
integer :: rowlen
integer :: last(0:2)
character(len=40) :: numstring = ''
print*,'Enter the N value'
read*, n
last(0) = n
write(numstring, '(i0)') n
rowlen = len_trim(numstring)
write(*,'(a)', advance='no') trim(numstring)
do i=1,3*n
if (mod(n,2) == 0) then
n = n/2
else
n = (3*n)+1
end if
write(numstring, '(a,i0)') ', ', n
rowlen = rowlen+len_trim(numstring)
if (rowlen > 39) then
write(*,'(a)') ','
write(numstring, '(i0)') n
rowlen = len_trim(numstring)
end if
write(*,'(a)', advance='no') trim(numstring)
last(mod(i,3)) = n
if (n == 1) EXIT
end do
write(*,*) ''
if (i > 2) then
write(*,*) 'Last three numbers:', last(mod(i-2,3)), &
& last(mod(i-1,3)), &
& last(mod(i,3))
end if
end program numbers
Upvotes: 1