Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- program circle
- implicit none
- integer :: n, m
- write(*, '(a)', advance='no') 'enter n: '
- read(*, *) n
- write(*, '(a)', advance='no') 'enter m: '
- read(*, *) m
- if (n > 0 .and. m > 0) then
- call killem(n, m)
- else
- stop "invalid parameters"
- end if
- contains
- subroutine killem(n, m)
- integer, intent(in) :: n, m
- integer :: men(n), i
- character(100) :: logfile, frmt
- ! enumerate the men
- do i = 1,n
- men(i) = i
- end do
- ! open log file
- write(logfile, '("log_n_",i0,"_m_",i0)') n, m
- open(unit=10, file=logfile)
- ! write out parameters
- write(10, '("n = ", i0, ", m = ", i0)') n, m
- ! count backwards from n downto 1; each step, the
- ! first i men are still alive
- do i = n, 1, -1
- ! write out all men that are still alive
- write(frmt, '("(",i0,"(i0,1x))")') i
- write(10, frmt) men(1 : i)
- ! move the first man to the back
- call rotate(1, men(1 : i))
- ! rotate the rest by m - 1, bringing the
- ! next victim to the front
- call rotate(m - 1, men(1 : i - 1))
- end do
- close(10)
- end subroutine
- ! rotate array a by m
- recursive subroutine rotate(m, a)
- integer, intent(in) :: m
- integer, intent(inout) :: a(:)
- integer :: i, tmp, s
- s = size(a)
- ! nothing to do
- if (m < 1 .or. s < 2) return
- if (m == 1) then ! base case
- ! save first element
- tmp = a(1)
- ! shift left
- a(1 : s - 1) = a(2 : s)
- ! put first element to the back
- a(s) = tmp
- else
- ! rotate m times by 1
- ! not very efficient, but who cares
- do i = 1, m
- call rotate(1, a)
- end do
- end if
- end subroutine
- end program
Add Comment
Please, Sign In to add comment