fast ↕list when (64≥≠list) ∧ ∧´list∊1‿2, typed result otherwise
This commit is contained in:
parent
3f0e696add
commit
88f2eb6b87
@ -39,54 +39,94 @@ B intRange(ux s, ux n) { // intended for s+n≥128; assumes n≥1
|
|||||||
return intRangeF64(s, n);
|
return intRangeF64(s, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
static B* ud_rec(B* p, usz d, usz r, i32* pos, usz* sh) {
|
#define UD_REC(T) static B* ud_rec_##T(B* p, usz d, usz r, void* pos0, usz* sh) { \
|
||||||
usz cl = sh[d];
|
T* pos = pos0; \
|
||||||
if (d+1==r) {
|
usz cl = sh[d]; \
|
||||||
|
if (d+1==r) { \
|
||||||
for (usz i = 0; i < cl; i++) {
|
for (usz i = 0; i < cl; i++) { \
|
||||||
i32* p1; *p = m_i32arrv(&p1, r);
|
T* p1; *p = m_##T##arrv(&p1, r); \
|
||||||
NOUNROLL for (usz i = 0; i < d; i++) p1[i] = pos[i];
|
NOUNROLL for (ux i = 0; i < d; i++) { \
|
||||||
p1[d] = i;
|
p1[i] = pos[i]; \
|
||||||
p++;
|
} \
|
||||||
}
|
p1[d] = i; \
|
||||||
} else {
|
p++; \
|
||||||
for (usz i = 0; i < cl; i++) {
|
} \
|
||||||
pos[d] = i;
|
} else { \
|
||||||
p = ud_rec(p, d+1, r, pos, sh);
|
for (usz i = 0; i < cl; i++) { \
|
||||||
}
|
pos[d] = i; \
|
||||||
}
|
p = ud_rec_##T(p, d+1, r, pos, sh); \
|
||||||
return p;
|
} \
|
||||||
|
} \
|
||||||
|
return p; \
|
||||||
}
|
}
|
||||||
|
UD_REC(i8)
|
||||||
|
UD_REC(i16)
|
||||||
|
UD_REC(i32)
|
||||||
|
|
||||||
|
static u64 bit_reverse64_low(u64 x, ux n) {
|
||||||
|
assert(n>0 && n<=64);
|
||||||
|
return bit_reverse64(x) >> (64-n);
|
||||||
|
}
|
||||||
|
B eq_c2(B,B,B);
|
||||||
NOINLINE B list_range(B x) {
|
NOINLINE B list_range(B x) {
|
||||||
SGetU(x)
|
SGetU(x)
|
||||||
usz xia = IA(x);
|
usz xia = IA(x);
|
||||||
if (RNK(x)!=1) thrF("↕𝕩: 𝕩 must be either an integer or integer list (had rank %i)", RNK(x));
|
if (RNK(x)!=1) thrF("↕𝕩: 𝕩 must be either an integer or integer list (had rank %i)", RNK(x));
|
||||||
if (xia>UR_MAX) thrF("↕𝕩: Result rank too large (%s≡≠𝕩)", xia);
|
if (xia>UR_MAX) thrF("↕𝕩: Result rank too large (%s≡≠𝕩)", xia);
|
||||||
if (xia==0) { decG(x); return m_funit(emptyIVec()); }
|
if (xia==0) { decG(x); return m_funit(emptyIVec()); }
|
||||||
usz sh[xia]; // stack allocation of rank items
|
|
||||||
i32 pos[xia];
|
i32 pos[xia]; // stack allocation of rank items; also used as i16[xia] and i8[xia]
|
||||||
usz ria = 1;
|
ShArr* sh;
|
||||||
bool bad=false, good=false;
|
usz ria, min, max;
|
||||||
for (usz i = xia; i--; ) {
|
ria = min = max = o2s(GetU(x, 0));
|
||||||
usz c = o2s(GetU(x, i));
|
bool bad = false;
|
||||||
sh[i] = c;
|
if (xia > 1) {
|
||||||
good|= c==0;
|
sh = m_shArr(xia);
|
||||||
bad|= (c > I32_MAX) | mulOn(ria, c);
|
sh->a[0] = min;
|
||||||
|
for (ux i = 1; i < xia; i++) {
|
||||||
|
usz c = o2s(GetU(x, i));
|
||||||
|
sh->a[i] = c;
|
||||||
|
bad|= mulOn(ria, c);
|
||||||
|
if (c > max) max = c;
|
||||||
|
if (c < min) min = c;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sh = NULL;
|
||||||
|
}
|
||||||
|
if ((bad && min!=0) || max > 1+(u64)I32_MAX) {
|
||||||
|
if (sh) mm_free((Value*) sh);
|
||||||
|
thrM("↕𝕩: Result too large");
|
||||||
}
|
}
|
||||||
if (bad && !good) thrM("↕𝕩: Result too large");
|
|
||||||
decG(x);
|
|
||||||
|
|
||||||
Arr* r = m_fillarr0p(ria);
|
Arr* r = m_fillarr0p(ria);
|
||||||
usz* rsh = arr_shAlloc(r, xia);
|
arr_shSetUO(r, xia, sh);
|
||||||
if (rsh) shcpy(rsh, sh, xia);
|
|
||||||
|
|
||||||
if (ria) {
|
if (ria) {
|
||||||
|
assert(min>0 && max>0);
|
||||||
B* rp = fillarrv_ptr(r);
|
B* rp = fillarrv_ptr(r);
|
||||||
ud_rec(rp, 0, xia, pos, sh);
|
if (MAY_F(max==2 && xia<=64)) {
|
||||||
|
x = toBitAny(C2(eq, x, m_f64(2)));
|
||||||
|
u64 m = bit_reverse64_low(~loadu_u64(bitany_ptr(x)), xia);
|
||||||
|
if (xia < 64) m&= (1ull<<xia)-1;
|
||||||
|
u64 c = m;
|
||||||
|
for (ux i = 0; i < ria; i++) {
|
||||||
|
u64* cr;
|
||||||
|
rp[i] = m_bitarrv(&cr, xia);
|
||||||
|
cr[0] = bit_reverse64_low(c &~ m, xia);
|
||||||
|
c = (c|m) + 1;
|
||||||
|
}
|
||||||
|
} else if (MAY_F(max <= 1+I8_MAX)) {
|
||||||
|
ud_rec_i8(rp, 0, xia, pos, PSH(r));
|
||||||
|
} else if (MAY_F(max <= 1+I16_MAX)) {
|
||||||
|
ud_rec_i16(rp, 0, xia, pos, PSH(r));
|
||||||
|
} else { // max checked before
|
||||||
|
ud_rec_i32(rp, 0, xia, pos, PSH(r));
|
||||||
|
}
|
||||||
fillarr_setFill(r, incG(rp[0]));
|
fillarr_setFill(r, incG(rp[0]));
|
||||||
} else {
|
} else {
|
||||||
fillarr_setFill(r, taga(arr_shVec(allZeroes(xia))));
|
fillarr_setFill(r, taga(arr_shVec(allZeroes(xia))));
|
||||||
}
|
}
|
||||||
|
decG(x);
|
||||||
return taga(r);
|
return taga(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -359,6 +359,13 @@ b←1↓1∾a←"hello" ⋄ b ⌽⎊'e' ⥊⟜1⍟2 5 ⋄ a ≡○•Hash b %% 1
|
|||||||
!"Expected non-negative integer, got character" % ↕"hi"
|
!"Expected non-negative integer, got character" % ↕"hi"
|
||||||
!"↕𝕩: 𝕩 must be either an integer or integer list (had rank 2)" % ↕2‿2⥊1
|
!"↕𝕩: 𝕩 must be either an integer or integer list (had rank 2)" % ↕2‿2⥊1
|
||||||
!"↕𝕩: Result rank too large (300≡≠𝕩)" % ↕300⥊1
|
!"↕𝕩: Result rank too large (300≡≠𝕩)" % ↕300⥊1
|
||||||
|
!"↕𝕩: Result too large" % ↕20⥊10
|
||||||
|
↕⟨⟩ %% <↕0
|
||||||
|
≢↕↕100 %% ↕100
|
||||||
|
↕⋈10 %% ⋈¨ ↕10
|
||||||
|
{! (⋈¨↕𝕩) ≡ ↕⋈𝕩}¨ 0‿1+⌜2⋆7‿15
|
||||||
|
{! ((<⟨⟩)<⊸∾⌜´ ↕¨ 𝕩) ≡ ↕𝕩}¨ 1+ (∾⟜-64‿63‿3‿5) ↑⌜ ⟨↕0,1,1‿1⟩
|
||||||
|
{! ((<⟨⟩)<⊸∾⌜´ ↕¨ 𝕩) ≡ ↕𝕩}¨ ⌽¨⊸∾ ⥊ 0‿1‿2 ⋈⌜ (126+↕7) ∾ 0‿1 + 2⋆15
|
||||||
|
|
||||||
# 𝕨↕𝕩
|
# 𝕨↕𝕩
|
||||||
!"𝕨↕𝕩: Length of 𝕨 must be at most rank of 𝕩" % 0↕0
|
!"𝕨↕𝕩: Length of 𝕨 must be at most rank of 𝕩" % 0↕0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user