エイトクィーンの解を配列の配列に保存するようにします。以前はI/Oで出力しておりました。
参照
2012-05-19 8クイーン http://d.hatena.ne.jp/fortran66/20120519
2012-12-19 配列の配列 http://d.hatena.ne.jp/fortran66/20121219
再帰を使うと簡潔に書けても実行時の負担が重くていまいちです。盤配置を返さず、可能な配置数だけを数えるようにした場合でも n=17 くらいで待ちきれない位の時間がかかります。
(参考:n=18 666090624 に数時間。寝る前に実行して明け方目を覚ましたら終わってた。)
実行結果
結果としては Deep Copy しているせいか時間がかかるようになった上に、n=13以上でトレースバックの出ない実行時エラーで死ぬようになりました。
配列の配列の初期化でサイズ0にするのに allocatable を使うしかないのが困りもの。
ソース・プログラム
module m_8 implicit none type :: t_list integer, allocatable :: i(:) end type t_list contains recursive subroutine eightq(list1, list2, lists) integer, intent(in) :: list1(:), list2(:) type(t_list), allocatable, intent(in out) :: lists(:) integer :: i type(t_list), allocatable :: tmp(:) if (size(list2) == 0) then tmp = [lists, t_list(list1)] ! deep copy call move_alloc(tmp, lists) else do i = 1, size(list2) if ( notdiag(list1, list2(i)) ) call eightq( [list1, list2(i)], pack(list2, list2 /= list2(i)), lists ) end do end if return end subroutine eightq logical function notdiag(list, k) integer, intent(in) :: list(:), k if (size(list) == 0) then notdiag = .true. else notdiag = all( abs(list - k) /= [size(list):1:-1] ) !non-standard [(i, i = size(list), 1, -1)] end if return end function notdiag end module m_8 program EightQueen use m_8 implicit none type(t_list), allocatable :: lists(:) integer :: i, n8 do n8 = 1, 10 allocate( lists(0) ) call eightq([integer::], [1:n8], lists) print '(a, i3, a, i10)', 'board size =', n8, ' possible solutions =', size(lists) do i = 1, size(lists) print '(i5, a, 25i3)', i, ':', lists(i)%i end do deallocate(lists) end do stop end program EightQueen