apl: n-queens via permute + diagonal filter, q(8)=92 (+10 tests, 306/306)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m5s

This commit is contained in:
2026-05-07 05:46:54 +00:00
parent 49eb22243a
commit e37167a58e
8 changed files with 89 additions and 8 deletions

View File

@@ -39,7 +39,7 @@ run_suite() {
EPOCHS
local OUTPUT
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMP" 2>/dev/null)
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMP" 2>/dev/null)
rm -f "$TMP"
local LINE

View File

@@ -865,6 +865,48 @@
(ones (apl-add (apl-mul cs (apl-scalar 0)) (apl-scalar 1))))
(apl-mandelbrot-step cs zero zero ones max-iter))))
(define
apl-insert-everywhere
(fn
(x lst)
(map
(fn (i) (append (take lst i) (cons x (drop lst i))))
(range 0 (+ (len lst) 1)))))
(define
apl-permutations
(fn
(n)
(if
(<= n 1)
(list (list 1))
(let
((sub (apl-permutations (- n 1))))
(reduce
(fn (acc p) (append acc (apl-insert-everywhere n p)))
(list)
sub)))))
(define
apl-queens-no-conflict?
(fn
(perm i j n)
(cond
((>= i n) true)
((>= j n) (apl-queens-no-conflict? perm (+ i 1) (+ i 2) n))
((= (abs (- i j)) (abs (- (nth perm i) (nth perm j)))) false)
(else (apl-queens-no-conflict? perm i (+ j 1) n)))))
(define
apl-queens-valid?
(fn (perm) (apl-queens-no-conflict? perm 0 1 (len perm))))
(define
apl-queens
(fn
(n)
(apl-scalar (len (filter apl-queens-valid? (apl-permutations n))))))
(define
apl-reduce
(fn

View File

@@ -5,9 +5,9 @@
"dfn": {"pass": 24, "fail": 0},
"tradfn": {"pass": 20, "fail": 0},
"valence": {"pass": 14, "fail": 0},
"programs": {"pass": 27, "fail": 0}
"programs": {"pass": 37, "fail": 0}
},
"total_pass": 296,
"total_pass": 306,
"total_fail": 0,
"total": 296
"total": 306
}

View File

@@ -9,8 +9,8 @@ _Generated by `lib/apl/conformance.sh`_
| dfn | 24 | 0 | 24 |
| tradfn | 20 | 0 | 20 |
| valence | 14 | 0 | 14 |
| programs | 27 | 0 | 27 |
| **Total** | **296** | **0** | **296** |
| programs | 37 | 0 | 37 |
| **Total** | **306** | **0** | **306** |
## Notes

View File

@@ -36,7 +36,7 @@ cat > "$TMPFILE" << 'EPOCHS'
(eval "(list apl-test-pass apl-test-fail)")
EPOCHS
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
LINE=$(echo "$OUTPUT" | awk '/^\(ok-len 4 / {getline; print; exit}')
if [ -z "$LINE" ]; then

View File

@@ -237,3 +237,23 @@
"mandelbrot c=-1.5 stays bounded"
(mkrv (apl-mandelbrot-1d (make-array (list 1) (list -1.5)) 100))
(list 100))
(apl-test "queens 1 → 1 solution" (mkrv (apl-queens 1)) (list 1))
(apl-test "queens 2 → 0 solutions" (mkrv (apl-queens 2)) (list 0))
(apl-test "queens 3 → 0 solutions" (mkrv (apl-queens 3)) (list 0))
(apl-test "queens 4 → 2 solutions" (mkrv (apl-queens 4)) (list 2))
(apl-test "queens 5 → 10 solutions" (mkrv (apl-queens 5)) (list 10))
(apl-test "queens 6 → 4 solutions" (mkrv (apl-queens 6)) (list 4))
(apl-test "queens 7 → 40 solutions" (mkrv (apl-queens 7)) (list 40))
(apl-test "queens 8 → 92 solutions" (mkrv (apl-queens 8)) (list 92))
(apl-test "permutations of 3 has 6" (len (apl-permutations 3)) 6)
(apl-test "permutations of 4 has 24" (len (apl-permutations 4)) 24)

View File

@@ -0,0 +1,18 @@
⍝ N-Queens — count solutions to placing N non-attacking queens on N×N
⍝ A solution is encoded as a permutation P of 1..N where P[i] is the
⍝ column of the queen in row i. Rows and columns are then automatically
⍝ unique (it's a permutation). We must additionally rule out queens
⍝ sharing a diagonal: |i-j| = |P[i]-P[j]| for any pair.
⍝ Backtracking via reduce — the classic Roger Hui style:
⍝ queens ← {≢{⍵,¨⍨↓(0=∊(¨⍳⍴⍵)≠.+|⍵)/⍳⍴⍵}/(⍳⍵)⍴⊂⍳⍵}
⍝ Plain reading:
⍝ permute 1..N, keep those where no two queens share a diagonal.
⍝ Known solution counts (OEIS A000170):
⍝ N 1 2 3 4 5 6 7 8 9 10
⍝ q(N) 1 0 0 2 10 4 40 92 352 724
queens {({(i j) (|i-j)|(P[i])-(P[j])}permutations )}