apl: quicksort recursive partition — Phase 6 classics complete (+9 tests, 315/315)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m0s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m0s
This commit is contained in:
@@ -907,6 +907,24 @@
|
|||||||
(n)
|
(n)
|
||||||
(apl-scalar (len (filter apl-queens-valid? (apl-permutations n))))))
|
(apl-scalar (len (filter apl-queens-valid? (apl-permutations n))))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
apl-quicksort
|
||||||
|
(fn
|
||||||
|
(arr)
|
||||||
|
(let
|
||||||
|
((ravel (get arr :ravel)))
|
||||||
|
(if
|
||||||
|
(<= (len ravel) 1)
|
||||||
|
arr
|
||||||
|
(let
|
||||||
|
((pivot (apl-scalar (first ravel))))
|
||||||
|
(let
|
||||||
|
((less (apl-quicksort (apl-compress (apl-lt arr pivot) arr)))
|
||||||
|
(eq (apl-compress (apl-eq arr pivot) arr))
|
||||||
|
(greater
|
||||||
|
(apl-quicksort (apl-compress (apl-gt arr pivot) arr))))
|
||||||
|
(apl-catenate less (apl-catenate eq greater))))))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
apl-reduce
|
apl-reduce
|
||||||
(fn
|
(fn
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
"dfn": {"pass": 24, "fail": 0},
|
"dfn": {"pass": 24, "fail": 0},
|
||||||
"tradfn": {"pass": 20, "fail": 0},
|
"tradfn": {"pass": 20, "fail": 0},
|
||||||
"valence": {"pass": 14, "fail": 0},
|
"valence": {"pass": 14, "fail": 0},
|
||||||
"programs": {"pass": 37, "fail": 0}
|
"programs": {"pass": 46, "fail": 0}
|
||||||
},
|
},
|
||||||
"total_pass": 306,
|
"total_pass": 315,
|
||||||
"total_fail": 0,
|
"total_fail": 0,
|
||||||
"total": 306
|
"total": 315
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ _Generated by `lib/apl/conformance.sh`_
|
|||||||
| dfn | 24 | 0 | 24 |
|
| dfn | 24 | 0 | 24 |
|
||||||
| tradfn | 20 | 0 | 20 |
|
| tradfn | 20 | 0 | 20 |
|
||||||
| valence | 14 | 0 | 14 |
|
| valence | 14 | 0 | 14 |
|
||||||
| programs | 37 | 0 | 37 |
|
| programs | 46 | 0 | 46 |
|
||||||
| **Total** | **306** | **0** | **306** |
|
| **Total** | **315** | **0** | **315** |
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|||||||
@@ -257,3 +257,50 @@
|
|||||||
(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)
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort empty"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 0) (list))))
|
||||||
|
(list))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort single"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 1) (list 42))))
|
||||||
|
(list 42))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort already sorted"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 5) (list 1 2 3 4 5))))
|
||||||
|
(list 1 2 3 4 5))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort reverse sorted"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 5) (list 5 4 3 2 1))))
|
||||||
|
(list 1 2 3 4 5))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort with duplicates"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 7) (list 3 1 4 1 5 9 2))))
|
||||||
|
(list 1 1 2 3 4 5 9))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort all equal"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 5) (list 7 7 7 7 7))))
|
||||||
|
(list 7 7 7 7 7))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort negatives"
|
||||||
|
(mkrv (apl-quicksort (make-array (list 5) (list -3 1 -1 2 0))))
|
||||||
|
(list -3 -1 0 1 2))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort 11-element pi"
|
||||||
|
(mkrv
|
||||||
|
(apl-quicksort (make-array (list 11) (list 3 1 4 1 5 9 2 6 5 3 5))))
|
||||||
|
(list 1 1 2 3 3 4 5 5 5 6 9))
|
||||||
|
|
||||||
|
(apl-test
|
||||||
|
"quicksort preserves length"
|
||||||
|
(first
|
||||||
|
(mksh (apl-quicksort (make-array (list 7) (list 3 1 4 1 5 9 2)))))
|
||||||
|
7)
|
||||||
|
|||||||
25
lib/apl/tests/programs/quicksort.apl
Normal file
25
lib/apl/tests/programs/quicksort.apl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
⍝ Quicksort — the classic Roger Hui one-liner
|
||||||
|
⍝
|
||||||
|
⍝ Q ← {1≥≢⍵:⍵ ⋄ (∇⍵⌿⍨⍵<p),(p=⍵)/⍵,∇⍵⌿⍨⍵>p←⍵⌷⍨?≢⍵}
|
||||||
|
⍝
|
||||||
|
⍝ Read right-to-left:
|
||||||
|
⍝ ?≢⍵ : pick a random index in 1..length
|
||||||
|
⍝ ⍵⌷⍨… : take that element as pivot p
|
||||||
|
⍝ ⍵>p : boolean — elements greater than pivot
|
||||||
|
⍝ ∇⍵⌿⍨… : recursively sort the > partition
|
||||||
|
⍝ (p=⍵)/⍵ : keep elements equal to pivot
|
||||||
|
⍝ ⍵<p : boolean — elements less than pivot
|
||||||
|
⍝ ∇⍵⌿⍨… : recursively sort the < partition
|
||||||
|
⍝ , : catenate ⟨less⟩ ⟨equal⟩ ⟨greater⟩
|
||||||
|
⍝ 1≥≢⍵:⍵ : guard — base case for length ≤ 1
|
||||||
|
⍝
|
||||||
|
⍝ Stability: not stable on duplicates (but eq-class is preserved as a block).
|
||||||
|
⍝ Worst case O(N²) on already-sorted input with deterministic pivot;
|
||||||
|
⍝ randomized pivot selection gives expected O(N log N).
|
||||||
|
⍝
|
||||||
|
⍝ Examples:
|
||||||
|
⍝ Q 3 1 4 1 5 9 2 6 5 3 5 → 1 1 2 3 3 4 5 5 5 6 9
|
||||||
|
⍝ Q ⍳0 → ⍬ (empty)
|
||||||
|
⍝ Q ,42 → 42
|
||||||
|
|
||||||
|
quicksort ← {1≥≢⍵:⍵ ⋄ p←⍵⌷⍨?≢⍵ ⋄ (∇⍵⌿⍨⍵<p),(p=⍵)/⍵,∇⍵⌿⍨⍵>p}
|
||||||
@@ -94,12 +94,12 @@ Core mapping:
|
|||||||
- [x] `lib/apl/conformance.sh` + runner, `scoreboard.json` + `scoreboard.md`
|
- [x] `lib/apl/conformance.sh` + runner, `scoreboard.json` + `scoreboard.md`
|
||||||
|
|
||||||
### Phase 6 — classic programs + drive corpus
|
### Phase 6 — classic programs + drive corpus
|
||||||
- [ ] Classic programs in `lib/apl/tests/programs/`:
|
- [x] Classic programs in `lib/apl/tests/programs/`:
|
||||||
- [x] `life.apl` — Conway's Game of Life as a one-liner using `⊂` `⊖` `⌽` `+/`
|
- [x] `life.apl` — Conway's Game of Life as a one-liner using `⊂` `⊖` `⌽` `+/`
|
||||||
- [x] `mandelbrot.apl` — complex iteration with rank-polymorphic `+ × ⌊` (or real-axis subset)
|
- [x] `mandelbrot.apl` — complex iteration with rank-polymorphic `+ × ⌊` (or real-axis subset)
|
||||||
- [x] `primes.apl` — `(2=+⌿0=A∘.|A)/A←⍳N` sieve
|
- [x] `primes.apl` — `(2=+⌿0=A∘.|A)/A←⍳N` sieve
|
||||||
- [x] `n-queens.apl` — backtracking via reduce
|
- [x] `n-queens.apl` — backtracking via reduce
|
||||||
- [ ] `quicksort.apl` — the classic Roger Hui one-liner
|
- [x] `quicksort.apl` — the classic Roger Hui one-liner
|
||||||
- [ ] System functions: `⎕FMT`, `⎕FR` (float repr), `⎕TS` (timestamp), `⎕IO`, `⎕ML` (migration level — fixed at 1), `⎕←` (print)
|
- [ ] System functions: `⎕FMT`, `⎕FR` (float repr), `⎕TS` (timestamp), `⎕IO`, `⎕ML` (migration level — fixed at 1), `⎕←` (print)
|
||||||
- [ ] Drive corpus to 100+ green
|
- [ ] Drive corpus to 100+ green
|
||||||
- [ ] Idiom corpus — `lib/apl/tests/idioms.sx` covering classic Roger Hui / Phil Last idioms
|
- [ ] Idiom corpus — `lib/apl/tests/idioms.sx` covering classic Roger Hui / Phil Last idioms
|
||||||
@@ -118,6 +118,7 @@ data; format for string templating.
|
|||||||
|
|
||||||
_Newest first._
|
_Newest first._
|
||||||
|
|
||||||
|
- 2026-05-07: Phase 6 quicksort — recursive less/eq/greater partition via apl-compress, deterministic-pivot variant; tests cover empty/single/sorted/reverse/duplicates/negatives; **all 5 classic programs done**; +9 tests; 315/315
|
||||||
- 2026-05-07: Phase 6 n-queens — permutation enumerate + diagonal-conflict filter; counts q(1..8) = 1,0,0,2,10,4,40,92 (OEIS A000170); apl-permutations + apl-queens; bumped test timeout 60→180s for q(8); +10 tests; 306/306
|
- 2026-05-07: Phase 6 n-queens — permutation enumerate + diagonal-conflict filter; counts q(1..8) = 1,0,0,2,10,4,40,92 (OEIS A000170); apl-permutations + apl-queens; bumped test timeout 60→180s for q(8); +10 tests; 306/306
|
||||||
- 2026-05-07: Phase 6 mandelbrot real-axis — apl-mandelbrot-1d batched z=z²+c with permanent alive-mask; c∈{-2,-1,0,0.25} bounded, c=1→3, c=0.5→5, c=2→2; +9 tests; 296/296
|
- 2026-05-07: Phase 6 mandelbrot real-axis — apl-mandelbrot-1d batched z=z²+c with permanent alive-mask; c∈{-2,-1,0,0.25} bounded, c=1→3, c=0.5→5, c=2→2; +9 tests; 296/296
|
||||||
- 2026-05-07: Phase 6 life — Conway via 9-shift toroidal sum + alive-rule (cnt=3 OR alive∧cnt=4); apl-life-step + life.apl source; blinker oscillates, block stable, glider advances; +7 tests; 287/287
|
- 2026-05-07: Phase 6 life — Conway via 9-shift toroidal sum + alive-rule (cnt=3 OR alive∧cnt=4); apl-life-step + life.apl source; blinker oscillates, block stable, glider advances; +7 tests; 287/287
|
||||||
|
|||||||
Reference in New Issue
Block a user