昨日のバージョンでは、整数の分割は画面出力されるだけで、データとして値を返していませんでした。これを配列の配列として返すことを考えます。整数配列を要素として持つ構造体を返すことにします。
返り値となる割り付け配列の大きさを増加させていくために、Fortran2003 で導入された組み込みサブルーチン move_alloc を用いました。この方法では、サイズを増やす毎に、要素の全コピーによる移動が行われるので無駄な事をすることになりますが、データ量が小さいので良しとします。(追記2012-07-27 記述が混乱していますが、move_alloc 自体は allocatable 配列のポインタ移動を実現する機能として導入されれた命令と思われますので、この命令では全コピーは行われないと思います。)
また割り付け配列の再割り付け機能も用いています。intel fortran の場合、この機能を利用するにはコンパイラのオプションで文法を Fortran2003 解釈に従うようにする必要があります。
ソース・プログラム
module m_partition implicit none type :: t_part integer, allocatable :: l(:) end type t_part contains function partition(n) integer, intent(in) :: n type (t_part), allocatable :: pl(:), partition(:) call parti([integer::], n, n, pl) ! [] zero-sized integer array partition = pl return end function partition recursive subroutine parti(list, n, n0, pl) integer, intent(in) :: list(:), n, n0 type (t_part), allocatable, intent(in out) :: pl(:) type (t_part), allocatable :: tmp(:) integer :: i if (n == 0) then call move_alloc(pl, tmp) pl = [tmp, t_part(list)] else do i = n - n0, n - 1 call parti([list, n - i], i, min(i, n - i), pl) end do end if return end subroutine parti end module m_partition program part use m_partition implicit none type (t_part), allocatable :: q(:) integer :: k, i do k = 1, 7 q = partition(k) print *, 'the number of partitons of ', k, ' = ', size(q) do i = 1, size(q) print '(25i3)', q(i)%l end do end do stop end program part