apl: ⍸ where — monadic indices-of-truthy + dyadic interval-index
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 51s

- apl-where (monadic): ravel scan, filter non-zero, +⎕IO offsets
- apl-interval-index (dyadic): count of breaks ≤ y; broadcasts over
  scalar or vector Y
- Wired into apl-monadic-fn / apl-dyadic-fn cond chains
- +10 pipeline tests covering both arities, ⎕IO offsetting, edge cases
  (empty mask, all-truthy, y below/above all breaks)
- pipeline 109/109
This commit is contained in:
2026-05-08 22:35:35 +00:00
parent 58c6ec27f3
commit 8cdebbe305
4 changed files with 71 additions and 1 deletions

View File

@@ -827,6 +827,31 @@
((new-ravel (reduce (fn (acc r) (append acc (map (fn (j) (nth ravel (+ (* r cols) j))) (range 0 cols)))) (list) kept-rows)))
(make-array (cons (len kept-rows) (rest shape)) new-ravel))))))))
(define
apl-where
(fn
(arr)
(let
((ravel (get arr :ravel)) (io (disclose (apl-quad-io))))
(let
((indices (filter (fn (i) (not (= (nth ravel i) 0))) (range 0 (len ravel)))))
(apl-vector (map (fn (i) (+ i io)) indices))))))
(define
apl-interval-index
(fn
(breaks vals)
(let
((b-ravel (get breaks :ravel))
(v-ravel
(if (scalar? vals) (list (disclose vals)) (get vals :ravel))))
(let
((result (map (fn (y) (len (filter (fn (b) (<= b y)) b-ravel))) v-ravel)))
(if
(scalar? vals)
(apl-scalar (first result))
(make-array (get vals :shape) result))))))
(define
apl-primes
(fn

View File

@@ -455,3 +455,45 @@
(list 1 2 3))
(apl-test "⍕ 42 → \"42\" (alias for ⎕FMT)" (apl-run "⍕ 42") "42")
(begin
(apl-test
"⍸ where: indices of truthy cells"
(mkrv (apl-run "⍸ 0 1 0 1 1"))
(list 2 4 5))
(apl-test
"⍸ where: leading truthy"
(mkrv (apl-run "⍸ 1 0 0 1 1"))
(list 1 4 5))
(apl-test
"⍸ where: all-zero → empty"
(mkrv (apl-run "⍸ 0 0 0"))
(list))
(apl-test
"⍸ where: all-truthy"
(mkrv (apl-run "⍸ 1 1 1"))
(list 1 2 3))
(apl-test
"⍸ where: ⎕IO=1 (1-based)"
(mkrv (apl-run "⍸ (5)=3"))
(list 3))
(apl-test
"⍸ interval-index: 2 4 6 ⍸ 5 → 2"
(mkrv (apl-run "2 4 6 ⍸ 5"))
(list 2))
(apl-test
"⍸ interval-index: 2 4 6 ⍸ 1 3 5 6 7 → 0 1 2 3 3"
(mkrv (apl-run "2 4 6 ⍸ 1 3 5 6 7"))
(list 0 1 2 3 3))
(apl-test
"⍸ interval-index: 5 ⍸ 3 → 3"
(mkrv (apl-run "(5) ⍸ 3"))
(list 3))
(apl-test
"⍸ interval-index: y below all → 0"
(mkrv (apl-run "10 20 30 ⍸ 5"))
(list 0))
(apl-test
"⍸ interval-index: y above all → len breaks"
(mkrv (apl-run "10 20 30 ⍸ 100"))
(list 3)))

View File

@@ -46,6 +46,7 @@
((= g "⍕") apl-quad-fmt)
((= g "⎕FMT") apl-quad-fmt)
((= g "⎕←") apl-quad-print)
((= g "⍸") apl-where)
(else (error "no monadic fn for glyph")))))
(define
@@ -90,6 +91,7 @@
((= g "⍉") apl-transpose-dyadic)
((= g "⊢") (fn (a b) b))
((= g "⊣") (fn (a b) a))
((= g "⍸") apl-interval-index)
(else (error "no dyadic fn for glyph")))))
(define