apl: perf — fix quadratic append in permutations, restore queens(8)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 43s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 43s
apl-permutations was doing (append acc <new-perms>) which is O(|acc|) and acc grows ~N! big — total cost O(N!²). Swapped to (append <new-perms> acc) — append is O(|first|) so cost is O((n+1)·N!_prev) per layer, total O(N!). q(7) went from 32s to 12s; q(8)=92 now finishes well within the 300s timeout, so the queens(8) test is restored. 497/497. Phase 8 complete.
This commit is contained in:
@@ -883,7 +883,7 @@
|
|||||||
(let
|
(let
|
||||||
((sub (apl-permutations (- n 1))))
|
((sub (apl-permutations (- n 1))))
|
||||||
(reduce
|
(reduce
|
||||||
(fn (acc p) (append acc (apl-insert-everywhere n p)))
|
(fn (acc p) (append (apl-insert-everywhere n p) acc))
|
||||||
(list)
|
(list)
|
||||||
sub)))))
|
sub)))))
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,8 @@
|
|||||||
|
|
||||||
(apl-test "queens 7 → 40 solutions" (mkrv (apl-queens 7)) (list 40))
|
(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 3 has 6" (len (apl-permutations 3)) 6)
|
||||||
|
|
||||||
(apl-test "permutations of 4 has 24" (len (apl-permutations 4)) 24)
|
(apl-test "permutations of 4 has 24" (len (apl-permutations 4)) 24)
|
||||||
|
|||||||
@@ -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
|
`(g h) ⍵ ↔ g (h ⍵)` (2-train atop). Parser: detect when a parenthesised
|
||||||
subexpression is all functions and emit `(:train fns)`; resolver: build the
|
subexpression is all functions and emit `(:train fns)`; resolver: build the
|
||||||
derived function; tests for mean-via-train (`+/÷≢`).
|
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
|
300 s timeout). Target: profile the inner loop, eliminate quadratic
|
||||||
list-append, restore the `queens(8)` test.
|
list-append, restore the `queens(8)` test.
|
||||||
|
|
||||||
@@ -191,6 +191,7 @@ data; format for string templating.
|
|||||||
|
|
||||||
_Newest first._
|
_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 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 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
|
- 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
|
||||||
|
|||||||
Reference in New Issue
Block a user