Sync
This commit is contained in:
parent
6f050a029e
commit
776bba907c
3887 changed files with 59894 additions and 7280 deletions
|
|
@ -1,4 +1,4 @@
|
|||
Solve the [[WP:Eight_queens_puzzle|eight queens puzzle]]. You can extend the problem to solve the puzzle with a board of side NxN.
|
||||
Solve the [[WP:Eight_queens_puzzle|eight queens puzzle]]. You can extend the problem to solve the puzzle with a board of side NxN. Number of solutions for small values of N is [http://oeis.org/A000170 here].
|
||||
|
||||
;Cf.
|
||||
* [[Knight's tour]]
|
||||
|
|
|
|||
22
Task/N-queens-problem/Common-Lisp/n-queens-problem-1.lisp
Normal file
22
Task/N-queens-problem/Common-Lisp/n-queens-problem-1.lisp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(defun n-queens (n m)
|
||||
(if (= n 1)
|
||||
(loop for x from 1 to m collect (list x))
|
||||
(loop for sol in (n-queens (1- n) m) nconc
|
||||
(loop for col from 1 to m when
|
||||
(loop for row from 0 to (length sol) for c in sol
|
||||
always (and (/= col c)
|
||||
(/= (abs (- c col)) (1+ row)))
|
||||
finally (return (cons col sol)))
|
||||
collect it))))
|
||||
|
||||
(defun show-solution (b n)
|
||||
(loop for i in b do
|
||||
(format t "~{~A~^~}~%"
|
||||
(loop for x from 1 to n collect (if (= x i) "Q " ". "))))
|
||||
(terpri))
|
||||
|
||||
(let ((i 0) (n 8))
|
||||
(mapc #'(lambda (s)
|
||||
(format t "Solution ~a:~%" (incf i))
|
||||
(show-solution s n))
|
||||
(n-queens n n)))
|
||||
45
Task/N-queens-problem/Common-Lisp/n-queens-problem-2.lisp
Normal file
45
Task/N-queens-problem/Common-Lisp/n-queens-problem-2.lisp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
(defun queens (nmax)
|
||||
(let ((a (make-array `(,nmax)))
|
||||
(s (make-array `(,nmax)))
|
||||
(u (make-array `(,(- (* 4 nmax) 2)) :initial-element 0))
|
||||
y z i j p q r m (v nil))
|
||||
(dotimes (i nmax) (setf (aref a i) i))
|
||||
(loop for n from 1 to nmax do
|
||||
(tagbody
|
||||
(setf m 0 i 0 r (1- (* 2 n)))
|
||||
(go L40)
|
||||
L30
|
||||
(setf (aref s i) j (aref u p) 1 (aref u (+ q r)) 1)
|
||||
(incf i)
|
||||
L40
|
||||
(if (>= i n) (go L80))
|
||||
(setf j i)
|
||||
L50
|
||||
(setf y (aref a j) z (aref a i))
|
||||
(setf p (+ (- i y) (1- n)) q (+ i y))
|
||||
(setf (aref a i) y (aref a j) z)
|
||||
(if (and (zerop (aref u p)) (zerop (aref u (+ q r)))) (go L30))
|
||||
L60
|
||||
(incf j)
|
||||
(if (< j n) (go L50))
|
||||
L70
|
||||
(decf j)
|
||||
(if (= j i) (go L90))
|
||||
(rotatef (aref a i) (aref a j))
|
||||
(go L70)
|
||||
L80
|
||||
(incf m)
|
||||
L90
|
||||
(decf i)
|
||||
(if (minusp i) (go L100))
|
||||
(setf p (+ (- i (aref a i)) (1- n)) q (+ i (aref a i)) j (aref s i))
|
||||
(setf (aref u p) 0 (aref u (+ q r)) 0)
|
||||
(go L60)
|
||||
L100
|
||||
;(princ n) (princ " ") (princ m) (terpri)
|
||||
(push (cons n m) v)
|
||||
)) (reverse v)))
|
||||
|
||||
> (queens 14)
|
||||
((1 . 1) (2 . 0) (3 . 0) (4 . 2) (5 . 10) (6 . 4) (7 . 40) (8 . 92) (9 . 352)
|
||||
(10 . 724) (11 . 2680) (12 . 14200) (13 . 73712) (14 . 365596))
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import std.stdio, std.conv;
|
||||
|
||||
uint nQueens(in uint nn) pure nothrow
|
||||
ulong nQueens(in uint nn) pure nothrow
|
||||
in {
|
||||
assert(nn > 0 && nn <= 27,
|
||||
"'side' value must be in 1 .. 27.");
|
||||
|
|
@ -12,9 +12,9 @@ in {
|
|||
immutable uint full = uint.max - ((1 << (ulen - nn)) - 1);
|
||||
immutable n = nn - 3;
|
||||
|
||||
uint count;
|
||||
typeof(return) count;
|
||||
uint[32] l=void, r=void, c=void;
|
||||
uint[33] mm; // mm and mmi are a stack
|
||||
uint[33] mm; // mm and mmi are a stack.
|
||||
|
||||
// Require second queen to be left of the first queen, so
|
||||
// we ever only test half of the possible solutions. This
|
||||
|
|
@ -24,22 +24,22 @@ in {
|
|||
uint d = n;
|
||||
// c: columns occupied by previous queens.
|
||||
c[n] = b0 | b1;
|
||||
// l: columns attacked by left diagonals
|
||||
// l: columns attacked by left diagonals.
|
||||
l[n] = (b0 << 2) | (b1 << 1);
|
||||
// r: by right diagnoals
|
||||
// r: by right diagnoals.
|
||||
r[n] = (b0 >> 2) | (b1 >> 1);
|
||||
|
||||
// availabe columns on current row
|
||||
// Availabe columns on current row.
|
||||
uint bits = full & ~(l[n] | r[n] | c[n]);
|
||||
|
||||
uint mmi = 1;
|
||||
mm[mmi] = bits;
|
||||
|
||||
while (bits) {
|
||||
// d: depth, aka row. counting backwards
|
||||
// because !d is often faster than d != n
|
||||
// d: depth, aka row. counting backwards.
|
||||
// Because !d is often faster than d != n.
|
||||
while (d) {
|
||||
// pos is right most nonzero bit
|
||||
// immutable uint pos = 1U << bits.bsf; // Slower.
|
||||
immutable uint pos = -(cast(int)bits) & bits;
|
||||
|
||||
// Mark bit used. Only put current bits on
|
||||
|
|
@ -53,9 +53,9 @@ in {
|
|||
}
|
||||
|
||||
d--;
|
||||
l[d] = (l[d+1] | pos) << 1;
|
||||
r[d] = (r[d+1] | pos) >> 1;
|
||||
c[d] = c[d+1] | pos;
|
||||
l[d] = (l[d + 1] | pos) << 1;
|
||||
r[d] = (r[d + 1] | pos) >> 1;
|
||||
c[d] = c[d + 1] | pos;
|
||||
|
||||
bits = full & ~(l[d] | r[d] | c[d]);
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ in {
|
|||
return count * 2;
|
||||
}
|
||||
|
||||
void main(string[] args) {
|
||||
immutable int side = (args.length >= 2) ? to!int(args[1]) : 8;
|
||||
writefln("N-queens(%d) = %d solutions.", side, nQueens(side));
|
||||
void main(in string[] args) {
|
||||
immutable uint side = (args.length >= 2) ? args[1].to!uint : 8;
|
||||
writefln("N-queens(%d) = %d solutions.", side, side.nQueens);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,106 +1,122 @@
|
|||
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
|
||||
program queens
|
||||
use omp_lib
|
||||
implicit none
|
||||
integer, parameter :: long = selected_int_kind(17)
|
||||
integer, parameter :: l = 18
|
||||
integer :: n, i, j, a(l*l, 2), k, p, q
|
||||
integer(long) :: s, b(l*l)
|
||||
real(kind(1d0)) :: t1, t2
|
||||
|
||||
do n = 6, l
|
||||
k = 0
|
||||
p = n/2
|
||||
q = mod(n, 2)*(p + 1)
|
||||
do i = 1, n
|
||||
do j = 1, n
|
||||
if ((abs(i - j) > 1) .and. ((i <= p) .or. ((i == q) .and. (j < 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()
|
||||
!$omp parallel do schedule(dynamic)
|
||||
do i = 1, k
|
||||
b(i) = pqueens(n, a(i, 1), a(i, 2))
|
||||
end do
|
||||
!$omp end parallel do
|
||||
t2 = omp_get_wtime()
|
||||
print "(I4, I12, F12.3)", n, 2*sum(b(1:k)), t2 - t1
|
||||
end do
|
||||
|
||||
contains
|
||||
function pqueens(n, k1, k2) result(m)
|
||||
implicit none
|
||||
integer(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 i = 1, n
|
||||
a(i) = i
|
||||
end do
|
||||
|
||||
do i = 1, 4*n - 2
|
||||
u(i) = 0
|
||||
end do
|
||||
|
||||
m = 0
|
||||
r = 2*n - 1
|
||||
if (k1 == k2) return
|
||||
|
||||
p = 1 - k1 + n
|
||||
q = 1 + k1 - 1
|
||||
if ((u(p) /= 0) .or. (u(q + r) /= 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) /= 0) .or. (u(q + r) /= 0)) return
|
||||
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
if (k2 /= 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 > 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) == 0) .and. (u(q + r) == 0)) go to 30
|
||||
|
||||
60 j = j + 1
|
||||
if (j <= n) go to 50
|
||||
|
||||
70 j = j - 1
|
||||
if (j == i) go to 90
|
||||
|
||||
z = a(i)
|
||||
a(i) = a(j)
|
||||
a(j) = z
|
||||
go to 70
|
||||
|
||||
!valid queens position found
|
||||
80 m = m + 1
|
||||
|
||||
90 i = i - 1
|
||||
if (i == 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 program
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ file=1; rank=1; q=0 /*starting place, # of queens. */
|
|||
/*═════════════════════════════════════find solution: N queens problem.*/
|
||||
do while q<N /*keep placing queens until done.*/
|
||||
@.file.rank=1 /*place a queen on the chessboard*/
|
||||
if safe?(file,rank) then do; q=q+1 /*if not being attached, eureka! */
|
||||
if safe?(file,rank) then do; q=q+1 /*if not being attacked, eureka! */
|
||||
file=1 /*another attempt at file #1, */
|
||||
rank=rank+1 /*and also bump the rank pointer.*/
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue