June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -0,0 +1,6 @@
(ns queens
(:require [clojure.math.combinatorics :as combo]
(defn queens [n]
(filter (fn [x] (every? #(apply distinct? (map-indexed % x)) [+ -]))
(combo/permutations (range 1 (inc n)))))

View file

@ -0,0 +1,5 @@
not_diagonal(X, N) :-
maplist(plus, X, N, Z1), maplist(plus, X, Z2, N), is_set(Z1), is_set(Z2).
queens(N, Qs) :-
numlist(1, N, P), findall(Q, (permutation(P, Q), not_diagonal(Q, P)), Qs).

View file

@ -3,11 +3,11 @@ parse arg N . /*obtain optional argument from
if N=='' | N=="," then N=8 /*Not specified: Then use the default.*/
if N<1 then signal nOK /*display a message, the board is bad. */
rank=1; file=1; #=0 /*starting rank&file; #≡number queens.*/
@.=0; pad=left('', 9* (N<18)) /*define empty board; set indentation.*/
@.=0; pad=left('', 9* (N<18) ) /*define empty board; set indentation.*/
/* [↓] rank&file ≡ chessboard row&cols*/
do while #<N; @.file.rank=1 /*keep placing queens until we're done.*/
if ok(file, rank) then do; #=#+1; rank=rank+1 /*Queen not being attacked? Then eureka*/
file=1 /*use another attempt at another file. */
if ok(file, rank) then do; #=#+1; file=1 /*Queen not being attacked? Then eureka*/
rank=rank+1 /*use another attempt at another rank. */
iterate /*go and try another queen placement. */
end /* [↑] found a good queen placement. */
@.file.rank=0 /*It isn't safe. So remove this queen.*/
@ -21,8 +21,8 @@ rank=1; file=1; #=0 /*starting rank&file; #≡numb
say 'A solution for ' N " queens:"; g=substr( copies("╬═══", N) ,2); say
say pad translate(''g"", '', "") /*display the top rank (of the board).*/
line = ''g""; dither='' /*define a line (bar) for cell boundry.*/
bar = '' ; queen='Q' /*kinds: horizontal, vertical, salad. */
line = ''g""; dither= '' /*define a line (bar) for cell boundry.*/
bar = '' ; queen = "Q" /*kinds: horizontal, vertical, salad. */
Bqueen = dither || queen || dither /*glyph befitting a black─square queen.*/
Wqueen = ' 'queen" " /* " " " white─square " */

View file

@ -0,0 +1,31 @@
func N_queens_solution(N = 8) {
func collision(field, row) {
for i in (^row) {
var distance = (field[i] - field[row])
distance ~~ [0, row-i, i-row] && return true
}
return false
}
func search(field, row) {
row == N && return field
for i in (^N) {
field[row] = i
if (!collision(field, row)) {
return (__FUNC__(field, row+1) || next)
}
}
return []
}
for i in (0 .. N>>1) {
if (var r = search([i], 1)) {
return r
}
}
}
for n in (1..15) {
say "#{'%2d' % n}: #{N_queens_solution(n) || 'No solution'}"
}

View file

@ -9,34 +9,32 @@ real matrix queens(real scalar n) {
s = J(1, n, 0)
u = J(1, 2*n-1, 1)
v = J(1, 2*n-1, 1)
i = j = 1
L1: k = a[j]
a[j] = a[i]
a[i] = k
i = 1
L1: if (i > n) {
m = m\a
goto L4
}
j=i
L2: k = a[j]
p = i-k+n
q = i+k-1
if (u[p] & v[q]) {
s[i++] = j
u[p] = v[q] = 0
if (i > n) {
m = m\a
goto L3
}
j = i
a[j] = a[i]
a[i] = k
s[i++] = j
goto L1
}
L2: if (++j <= n) goto L1
while (--j > i) {
k = a[i]
a[i] = a[j]
a[j] = k
}
L3: if (--i == 0) return(m)
p = i-a[i]+n
q = i+a[i]-1
L3: if (++j <= n) goto L2
L4: if (--i == 0) return(m)
j = s[i]
k = a[i]
a[i] = a[j]
a[j] = k
p = i-k+n
q = i+k-1
u[p] = v[q] = 1
goto L2
goto L3
}
a = queens(8)

View file

@ -1,5 +1,5 @@
mata
real matrix queens(real scalar n) {
real matrix queens_rec(real scalar n) {
real rowvector a, u, v
real matrix m
@ -13,46 +13,25 @@ real matrix queens(real scalar n) {
void queens_aux(real scalar n, real scalar i, real rowvector a,
real rowvector u, real rowvector v, real matrix m) {
real scalar j, k, s
real scalar j, k
if (i > n) {
m = m\a
} else {
for (k = i; k <= n; k++) {
j = a[k]
p = i+j-1
q = i-j+n
for (j = i; j <= n; j++) {
k = a[j]
p = i-k+n
q = i+k-1
if (u[p] & v[q]) {
u[p] = v[q] = 0
s = a[i]
a[i] = a[k]
a[k] = s
a[j] = a[i]
a[i] = k
queens_aux(n, i+1, a, u, v, m)
u[p] = v[q] = 1
s = a[i]
a[i] = a[k]
a[k] = s
a[i] = a[j]
a[j] = k
}
}
}
}
a = queens(8)
e = I(8)
1:/e[a[1,.],.]
1 2 3 4 5 6 7 8
+---------------------------------+
1 | 1 . . . . . . . |
2 | . . . . 1 . . . |
3 | . . . . . . . 1 |
4 | . . . . . 1 . . |
5 | . . 1 . . . . . |
6 | . . . . . . 1 . |
7 | . 1 . . . . . . |
8 | . . . 1 . . . . |
+---------------------------------+
rows(a)
92
end

View file

@ -0,0 +1,2 @@
queens(8) == queens_rec(8)
1

View file

@ -0,0 +1,24 @@
def (nqueens n queens)
prn "step: " queens # show progress
if (len.queens = n)
prn "solution! " queens
# else
let row (if queens (queens.zero.zero + 1) 0)
for col 0 (col < n) ++col
let new_queens (cons (list row col) queens)
if (no conflicts.new_queens)
(nqueens n new_queens)
# check if the first queen in 'queens' lies on the same column or diagonal as
# any of the others
def (conflicts queens)
let (curr ... rest) queens
or (let curr_column curr.1
(some (fn(_) (= _ curr_column))
(map cadr rest))) # columns
(some (fn(_) (diagonal_match curr _))
rest)
def (diagonal_match curr other)
(= (abs (curr.0 - other.0))
(abs (curr.1 - other.1)))