From ff0bfd34bb9023f1353be313c1da130cabf4f619 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sat, 5 Nov 2022 18:48:54 +0200 Subject: [PATCH] squeeze Grade result --- src/builtins/fns.c | 7 +++++-- src/builtins/grade.h | 37 ++++++++++++++++++++++++++----------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/builtins/fns.c b/src/builtins/fns.c index ccdf0d28..4bb02939 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -24,7 +24,8 @@ static B* ud_rec(B* p, usz d, usz r, i32* pos, usz* sh) { } return p; } -static Arr* bitUD[3]; +Arr* bitUD[3]; +B bit2x[2]; // ⟨0‿1 ⋄ 1‿0⟩ B ud_c1(B t, B x) { if (isAtm(x)) { usz xu = o2s(x); @@ -273,6 +274,7 @@ void fun_gcFn() { if (globalNames!=NULL) mm_visitP(globalNames); mm_visit(globalNameList); for (i32 i = 0; i < 3; i++) mm_visitP(bitUD[i]); + mm_visit(bit2x[1]); // bit2x[0] visited by ↑ } @@ -291,5 +293,6 @@ void fns_init() { TIi(t_funBI,fn_im) = funBI_im; bitUD[0] = a(emptyIVec()); { u64* p; B a=m_bitarrv(&p, 1); *p=0; bitUD[1] = a(a); } - { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,1,1); bitUD[2] = a(a); } + { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,1,1); bitUD[2] = a(a); bit2x[0] = a; } + { u64* p; B a=m_bitarrv(&p, 2); *p=0; bitp_set(p,0,1); bit2x[1] = a; } } diff --git a/src/builtins/grade.h b/src/builtins/grade.h index 8e9e0450..712acd58 100644 --- a/src/builtins/grade.h +++ b/src/builtins/grade.h @@ -203,12 +203,21 @@ B SORT_C1(B t, B x) { #define GRADE_CHR GRADE_UD("⍋","⍒") +extern Arr* bitUD[3]; // from fns.c +extern B bit2x[2]; B GRADE_CAT(c1)(B t, B x) { if (isAtm(x) || RNK(x)==0) thrM(GRADE_CHR": Argument cannot be a unit"); if (RNK(x)>1) x = toCells(x); usz ia = IA(x); if (ia>I32_MAX) thrM(GRADE_CHR": Argument too large"); - if (ia==0) { decG(x); return emptyIVec(); } + if (ia<=2) { + B r; + if (ia==2) { SGetU(x); r = incG(bit2x[!(compare(GetU(x,0), GetU(x,1)) GRADE_UD(<=,>=) 0)]); } + else if (ia==1) r = taga(ptr_inc(bitUD[1])); + else r = emptyIVec(); + decG(x); + return r; + } u8 xe = TI(x,elType); i32* rp; B r = m_i32arrv(&rp, ia); @@ -221,15 +230,15 @@ B GRADE_CAT(c1)(B t, B x) { if (bitp_get(xp,i)^GRADE_UD(0,1)) rp[r1++] = i; else rp[r0++] = i; } - decG(x); return r; + goto decG_sq; } else if (xe==el_i8 && ia>8) { i8* xp = i8any_ptr(x); usz n=ia; RADIX_SORT_i8(usz, GRADE); - decG(x); return r; + goto decG_sq; } else if (xe==el_i16 && ia>16) { i16* xp = i16any_ptr(x); usz n = ia; RADIX_SORT_i16(usz, GRADE, i32); - decG(x); return r; + goto decG_sq; } if (xe==el_i32 || xe==el_c32) { // safe to use the same comparison for i32 & c32 as c32 is 0≤x≤1114111 i32* xp = tyany_ptr(x); @@ -248,20 +257,19 @@ B GRADE_CAT(c1)(B t, B x) { 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; } + if (done) goto decG_sq; } 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; + TFREE(c0); goto decG_sq; } if (ia > 40) { usz n=ia; RADIX_SORT_i32(usz, GRADE, i32); - decG(x); return r; + goto decG_sq; } TALLOC(I32I32p, tmp, ia); @@ -271,8 +279,8 @@ B GRADE_CAT(c1)(B t, B x) { } CAT(GRADE_CAT(IP),tim_sort)(tmp, ia); for (usz i = 0; i < ia; i++) rp[i] = tmp[i].v; - TFREE(tmp); decG(x); - return r; + TFREE(tmp); + goto decG_sq; } SLOW1(GRADE_CHR"𝕩", x); @@ -284,7 +292,14 @@ B GRADE_CAT(c1)(B t, B x) { } CAT(GRADE_CAT(BP),tim_sort)(tmp, ia); for (usz i = 0; i < ia; i++) rp[i] = tmp[i].v; - TFREE(tmp); decG(x); + TFREE(tmp); + goto decG_sq; + + decG_sq:; + + if (ia<=(I8_MAX+1)) r = taga(cpyI8Arr(r)); + else if (ia<=(I16_MAX+1)) r = taga(cpyI16Arr(r)); + decG(x); return r; }