diff --git a/lib/apl/runtime.sx b/lib/apl/runtime.sx index 1eda54f3..07652f77 100644 --- a/lib/apl/runtime.sx +++ b/lib/apl/runtime.sx @@ -883,7 +883,7 @@ (let ((sub (apl-permutations (- n 1)))) (reduce - (fn (acc p) (append acc (apl-insert-everywhere n p))) + (fn (acc p) (append (apl-insert-everywhere n p) acc)) (list) sub))))) diff --git a/lib/apl/tests/programs.sx b/lib/apl/tests/programs.sx index 9c1fec8c..7d97976a 100644 --- a/lib/apl/tests/programs.sx +++ b/lib/apl/tests/programs.sx @@ -252,6 +252,8 @@ (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) diff --git a/plans/apl-on-sx.md b/plans/apl-on-sx.md index 55ca61c1..d4d689de 100644 --- a/plans/apl-on-sx.md +++ b/plans/apl-on-sx.md @@ -173,7 +173,7 @@ programs run from source, and starts pushing on performance. `(g h) ⍵ ↔ g (h ⍵)` (2-train atop). Parser: detect when a parenthesised subexpression is all functions and emit `(:train fns)`; resolver: build the derived function; tests for mean-via-train (`+/÷≢`). -- [ ] **Performance pass** — n-queens(8) currently ~30 s/iter (tight on the +- [x] **Performance pass** — n-queens(8) currently ~30 s/iter (tight on the 300 s timeout). Target: profile the inner loop, eliminate quadratic list-append, restore the `queens(8)` test. @@ -191,6 +191,7 @@ data; format for string templating. _Newest first._ +- 2026-05-07: Phase 8 step 6 — perf: swapped (append acc xs) → (append xs acc) in apl-permutations to make permutation generation linear instead of quadratic; q(7) 32s→12s; q(8)=92 test restored within 300s timeout; **Phase 8 complete, all unchecked items ticked**; 497/497 - 2026-05-07: Phase 8 step 5 — train/fork notation. Parser :lparen detects all-fn inner segments → emits :train AST; resolver covers 2-atop & 3-fork for both monadic and dyadic. `(+/÷≢) 1..5 → 3` (mean), `(- ⌊) 5 → -5` (atop), `2(+×-)5 → -21` (dyadic fork), `(⌈/-⌊/) → 8` (range); +6 tests; 496/496 - 2026-05-07: Phase 8 step 4 — programs-e2e.sx runs classic-algorithm shapes through full pipeline (factorial via ∇, triangulars, sum-of-squares, divisor-counts, prime-mask, named-fn composition, dyadic max-of-two, Newton step); also added ⌿ + ⍀ to glyph sets (were silently skipped); +15 tests; 490/490 - 2026-05-07: Phase 8 step 3 — multi-axis bracket A[I;J] / A[I;] / A[;J] via :bracket AST + apl-bracket-multi runtime; split-bracket-content scans :semi at depth 0; apl-cartesian builds index combinations; nil axis = "all"; scalar axis collapses; +8 tests; 475/475