diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 9f1e55a4..db917d34 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -76,9 +76,80 @@ B ud_c1(B t, B x) { return taga(r); } -extern B rt_ud; B ud_c2(B t, B w, B x) { - return c2(rt_ud, w, x); + usz wia=1; + if (isArr(w)) { + if (RNK(w)>1) thrM("↕: 𝕨 must have rank at most 1"); + wia = IA(w); + if (wia==0) { decG(w); return x; } + } + ur xr; + if (isAtm(x) || (xr=RNK(x)) UR_MAX) thrM("↕: Result rank too large"); + ur wr = wia; + ur rr = xr + wr; + ShArr* sh = m_shArr(rr); + usz* rsh = sh->a; + usz* wsh = rsh + wr; + if (isAtm(w)) { + wsh[0] = o2s(w); + } else { + SGetU(w) + for (usz i=0; i16 && wemax) max=c; } - i64 range = max - (i64)min + 1; + u64 range = max - (i64)min + 1; if (range/2 < ia) { - TALLOC(usz, tmp, range+1); - for (i64 i = 0; i < range+1; i++) tmp[i] = 0; - GRADE_UD( // i32 range-based - for (usz i = 0; i < ia; i++) (tmp-min+1)[xp[i]]++; - for (i64 i = 1; i < range; i++) tmp[i]+= tmp[i-1]; - for (usz i = 0; i < ia; i++) rp[(tmp-min)[xp[i]]++] = i; - , - for (usz i = 0; i < ia; i++) (tmp-min)[xp[i]]++; - for (i64 i = range-2; i >= 0; i--) tmp[i]+= tmp[i+1]; - for (usz i = 0; i < ia; i++) rp[(tmp-min+1)[xp[i]]++] = i; - ) - TFREE(tmp); decG(x); + // First try to invert it as a permutation + if (range==ia && sum==(i32)((i64)ia*(min+max)/2)) { + for (usz i = 0; i < ia; i++) rp[i]=ia; + for (usz i = 0; i < ia; i++) { i32 v=xp[i]; GRADE_UD(rp[v-min],rp[max-v])=i; } + bool done=1; for (usz i = 0; i < ia; i++) done &= rp[i]!=ia; + if (done) { decG(x); return r; } + } + TALLOC(usz, c0, range); usz *c0o=c0-min; + for (usz i = 0; i < range; i++) c0[i] = 0; + for (usz i = 0; i < ia; i++) c0o[xp[i]]++; + usz s=0; FOR (i, range) { usz p=s; s+=c0[i]; c0[i]=p; } + for (usz i = 0; i < ia; i++) rp[c0o[xp[i]]++] = i; + TFREE(c0); decG(x); return r; } if (ia > 40) { diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c index 8a77794f..5eb430ca 100644 --- a/src/builtins/selfsearch.c +++ b/src/builtins/selfsearch.c @@ -9,9 +9,10 @@ B memberOf_c1(B t, B x) { if (n==0) { decG(x); return emptyIVec(); } if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); + if (elChr(xe)) xe -= el_c8-el_i8; #define BRUTE(T) \ - i##T* xp = i##T##any_ptr(x); \ + i##T* xp = tyany_ptr(x); \ u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \ for (usz i=1; i8 && n3*n?tn:3*n)+(2*rx+1)*sizeof(usz))); @@ -95,9 +96,10 @@ B count_c1(B t, B x) { if (n>(usz)I32_MAX+1) thrM("βŠ’: Argument length >2⋆31 not supported"); if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); + if (elChr(xe)) xe -= el_c8-el_i8; #define BRUTE(T) \ - i##T* xp = i##T##any_ptr(x); \ + i##T* xp = tyany_ptr(x); \ i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ for (usz i=1; i8 && nn?tn:n)+(2*rx+1)*sizeof(usz))); @@ -186,9 +188,10 @@ B indexOf_c1(B t, B x) { if (n>(usz)I32_MAX+1) thrM("⊐: Argument length >2⋆31 not supported"); if (RNK(x)>1) x = toCells(x); u8 xe = TI(x,elType); + if (elChr(xe)) xe -= el_c8-el_i8; #define BRUTE(T) \ - i##T* xp = i##T##any_ptr(x); \ + i##T* xp = tyany_ptr(x); \ i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ TALLOC(i##T, uniq, n); uniq[0]=xp[0]; \ for (usz i=1, u=1; i8 && n