tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1,101 @@
program Nqueens
implicit none
integer, parameter :: n = 8 ! size of board
integer :: file = 1, rank = 1, queens = 0
integer :: i
logical :: board(n,n) = .false.
do while (queens < n)
board(file, rank) = .true.
if(is_safe(board, file, rank)) then
queens = queens + 1
file = 1
rank = rank + 1
else
board(file, rank) = .false.
file = file + 1
do while(file > n)
rank = rank - 1
if (rank < 1) then
write(*, "(a,i0)") "No solution for n = ", n
stop
end if
do i = 1, n
if (board(i, rank)) then
file = i
board(file, rank) = .false.
queens = queens - 1
file = i + 1
exit
end if
end do
end do
end if
end do
call Printboard(board)
contains
function is_safe(board, file, rank)
logical :: is_safe
logical, intent(in) :: board(:,:)
integer, intent(in) :: file, rank
integer :: i, f, r
is_safe = .true.
do i = rank-1, 1, -1
if(board(file, i)) then
is_safe = .false.
return
end if
end do
f = file - 1
r = rank - 1
do while(f > 0 .and. r > 0)
if(board(f, r)) then
is_safe = .false.
return
end if
f = f - 1
r = r - 1
end do
f = file + 1
r = rank - 1
do while(f <= n .and. r > 0)
if(board(f, r)) then
is_safe = .false.
return
end if
f = f + 1
r = r - 1
end do
end function
subroutine Printboard(board)
logical, intent(in) :: board(:,:)
character(n*4+1) :: line
integer :: f, r
write(*, "(a, i0)") "n = ", n
line = repeat("+---", n) // "+"
do r = 1, n
write(*, "(a)") line
do f = 1, n
write(*, "(a)", advance="no") "|"
if(board(f, r)) then
write(*, "(a)", advance="no") " Q "
else if(mod(f+r, 2) == 0) then
write(*, "(a)", advance="no") " "
else
write(*, "(a)", advance="no") "###"
end if
end do
write(*, "(a)") "|"
end do
write(*, "(a)") line
end subroutine
end program

View file

@ -0,0 +1,72 @@
C This one implements depth-first backtracking.
C See the 2nd program for Scheme on the "Permutations" page for the
C main idea.
C As is, the program only prints the number of n-queens configurations.
C To print also the configurations, uncomment the line after label 80.
program queens
implicit integer(a-z)
parameter(l=18)
dimension a(l),s(l),u(4*l-2)
do 10 i=1,l
10 a(i)=i
do 20 i=1,4*l-2
20 u(i)=0
do 110 n=1,l
m=0
i=1
r=2*n-1
go to 40
30 s(i)=j
u(p)=1
u(q+r)=1
i=i+1
40 if(i.gt.n) go to 80
j=i
50 z=a(i)
y=a(j)
p=i-y+n
q=i+y-1
a(i)=y
a(j)=z
if((u(p).eq.0).and.(u(q+r).eq.0)) goto 30
60 j=j+1
if(j.le.n) go to 50
70 j=j-1
if(j.eq.i) go to 90
z=a(i)
a(i)=a(j)
a(j)=z
go to 70
80 m=m+1
C print *,(a(k),k=1,n)
90 i=i-1
if(i.eq.0) go to 100
p=i-a(i)+n
q=i+a(i)-1
j=s(i)
u(p)=0
u(q+r)=0
go to 60
100 print *,n,m
110 continue
end
C Output
C 1 1
C 2 0
C 3 0
C 4 2
C 5 10
C 6 4
C 7 40
C 8 92
C 9 352
C 10 724
C 11 2680
C 12 14200
C 13 73712
C 14 365596
C 15 2279184
C 16 14772512
C 17 95815104
C 18 666090624

View file

@ -0,0 +1,106 @@
MODULE QUEENS_MOD
IMPLICIT NONE
INTEGER, PARAMETER :: LONG=SELECTED_INT_KIND(17)
CONTAINS
FUNCTION PQUEENS(N,K1,K2) RESULT(M)
IMPLICIT NONE
INTEGER(KIND=LONG) :: M
INTEGER, INTENT(IN) :: N,K1,K2
INTEGER, PARAMETER :: L=20
INTEGER :: A(L),S(L),U(4*L-2)
INTEGER :: I,J,Y,Z,P,Q,R
DO 10 I=1,N
10 A(I)=I
DO 20 I=1,4*N-2
20 U(I)=0
M=0
R=2*N-1
IF(K1.EQ.K2) RETURN
P=1-K1+N
Q=1+K1-1
IF((U(P).NE.0).OR.(U(Q+R).NE.0)) RETURN
U(P)=1
U(Q+R)=1
Z=A(1)
A(1)=A(K1)
A(K1)=Z
P=2-K2+N
Q=2+K2-1
IF((U(P).NE.0).OR.(U(Q+R).NE.0)) RETURN
U(P)=1
U(Q+R)=1
IF(K2.NE.1) THEN
Z=A(2)
A(2)=A(K2)
A(K2)=Z
ELSE
Z=A(2)
A(2)=A(K1)
A(K1)=Z
END IF
I=3
GO TO 40
30 S(I)=J
U(P)=1
U(Q+R)=1
I=I+1
40 IF(I.GT.N) GO TO 80
J=I
50 Z=A(I)
Y=A(J)
P=I-Y+N
Q=I+Y-1
A(I)=Y
A(J)=Z
IF((U(P).EQ.0).AND.(U(Q+R).EQ.0)) GO TO 30
60 J=J+1
IF(J.LE.N) GO TO 50
70 J=J-1
IF(J.EQ.I) GO TO 90
Z=A(I)
A(I)=A(J)
A(J)=Z
GO TO 70
80 M=M+1
90 I=I-1
IF(I.EQ.2) RETURN
P=I-A(I)+N
Q=I+A(I)-1
J=S(I)
U(P)=0
U(Q+R)=0
GO TO 60
END FUNCTION
END MODULE
PROGRAM QUEENS
USE OMP_LIB
USE QUEENS_MOD
IMPLICIT NONE
INTEGER, PARAMETER :: L=20
INTEGER :: N,I,J,A(L*L,2),K,P,Q
INTEGER(KIND=LONG) :: S,B(L*L)
DOUBLE PRECISION :: T1,T2
DO N=6,18
K=0
P=N/2
Q=MOD(N,2)*(P+1)
DO I=1,N
DO J=1,N
IF((ABS(I-J).GT.1).AND.((I.LE.P).OR.((I.EQ.Q).AND.(J.LT.I)))) THEN
K=K+1
A(K,1)=I
A(K,2)=J
END IF
END DO
END DO
S=0
T1=OMP_GET_WTIME()
C$OMP PARALLEL DO SCHEDULE(DYNAMIC)
DO I=1,K
B(I)=PQUEENS(N,A(I,1),A(I,2))
END DO
C$OMP END PARALLEL DO
T2=OMP_GET_WTIME()
PRINT '(I4,I12,F12.3)',N,2*SUM(B(1:K)),T2-T1
END DO
END PROGRAM