random deal & subset
This commit is contained in:
parent
fc4d36de07
commit
cce52dd40e
@ -199,24 +199,26 @@ B hash_c1(B t, B x) {
|
||||
|
||||
|
||||
static B rand_ns;
|
||||
static B rand_rangeName;
|
||||
static i32 rand_a, rand_b;
|
||||
static NFnDesc* rand_rangeDesc;
|
||||
static B rand_rangeName; static NFnDesc* rand_rangeDesc;
|
||||
static B rand_dealName; static NFnDesc* rand_dealDesc;
|
||||
static B rand_subsetName; static NFnDesc* rand_subsetDesc;
|
||||
#define RAND_START Scope* sc = c(NS,nfn_objU(t))->sc; \
|
||||
u64 seed = sc->vars[rand_a].u | sc->vars[rand_b].u<<32;
|
||||
#define RAND_END sc->vars[rand_a].u = seed>>32; \
|
||||
sc->vars[rand_a].u = seed&0xFFFFFFFF;
|
||||
B rand_range_c1(B t, B x) {
|
||||
i64 xv = o2i64(x);
|
||||
if (xv<0) thrM("(rand).Range: 𝕩 cannot be negative");
|
||||
Scope* sc = c(NS,nfn_objU(t))->sc;
|
||||
u64 seed = sc->vars[rand_a].u | sc->vars[rand_b].u<<32;
|
||||
RAND_START;
|
||||
u64 rnd = wyrand(&seed);
|
||||
sc->vars[rand_a].u = seed>>32;
|
||||
sc->vars[rand_a].u = seed&0xFFFFFFFF;
|
||||
RAND_END;
|
||||
return xv? m_f64(wy2u0k(rnd, xv)) : m_f64(wy2u01(rnd));
|
||||
}
|
||||
B rand_range_c2(B t, B w, B x) {
|
||||
Scope* sc = c(NS,nfn_objU(t))->sc;
|
||||
u64 seed = sc->vars[rand_a].u | sc->vars[rand_b].u<<32;
|
||||
usz am = o2s(w);
|
||||
i64 max = o2i64(x);
|
||||
RAND_START;
|
||||
B r;
|
||||
if (max<1) {
|
||||
if (max!=0) thrM("(rand).Range: 𝕩 cannot be negative");
|
||||
@ -230,15 +232,96 @@ B rand_range_c2(B t, B w, B x) {
|
||||
i32* rp; r = m_i32arrv(&rp, am);
|
||||
for (usz i = 0; i < am; i++) rp[i] = wy2u0k(wyrand(&seed), max);
|
||||
}
|
||||
sc->vars[rand_a].u = seed>>32;
|
||||
sc->vars[rand_a].u = seed&0xFFFFFFFF;
|
||||
RAND_END;
|
||||
return r;
|
||||
}
|
||||
|
||||
B rand_deal_c1(B t, B x) {
|
||||
i32 xi = o2i(x);
|
||||
if (RARE(xi<0)) thrM("(rand).Deal: Argument cannot be negative");
|
||||
if (xi==0) return emptyIVec();
|
||||
RAND_START;
|
||||
i32* rp; B r = m_i32arrv(&rp, xi);
|
||||
for (i64 i = 0; i < xi; i++) rp[i] = i;
|
||||
for (i64 i = 0; i < xi; i++) {
|
||||
i32 j = wy2u0k(wyrand(&seed), xi-i) + i;
|
||||
i32 c = rp[j];
|
||||
rp[j] = rp[i];
|
||||
rp[i] = c;
|
||||
}
|
||||
RAND_END;
|
||||
return r;
|
||||
}
|
||||
|
||||
B rand_deal_c2(B t, B w, B x) {
|
||||
i32 wi = o2i(w);
|
||||
i32 xi = o2i(x);
|
||||
if (RARE(wi<0)) thrM("(rand).Deal: 𝕨 cannot be negative");
|
||||
if (RARE(xi<0)) thrM("(rand).Deal: 𝕩 cannot be negative");
|
||||
if (RARE(wi>xi)) thrM("(rand).Deal: 𝕨 cannot exceed 𝕩");
|
||||
if (wi==0) return emptyIVec();
|
||||
RAND_START;
|
||||
TALLOC(i32,s,xi);
|
||||
for (i64 i = 0; i < xi; i++) s[i] = i;
|
||||
for (i64 i = 0; i < wi; i++) {
|
||||
i32 j = wy2u0k(wyrand(&seed), xi-i) + i;
|
||||
i32 c = s[j];
|
||||
s[j] = s[i];
|
||||
s[i] = c;
|
||||
}
|
||||
i32* rp; B r = m_i32arrv(&rp, wi);
|
||||
memcpy(rp, s, wi*4);
|
||||
TFREE(s);
|
||||
RAND_END;
|
||||
return r;
|
||||
}
|
||||
|
||||
#define N(X) X##_i2i
|
||||
#define KT i32
|
||||
#define HT i32
|
||||
#define H1(K) K
|
||||
#define H2(K,h1) h1
|
||||
#define H1R(K,h2) h2
|
||||
#define EMPTY(S,K) ((S)==0)
|
||||
#define HDEF 0
|
||||
#define EQUAL(A,B) (A)==(B)
|
||||
#define VALS
|
||||
#define VT i32
|
||||
#include "../utils/hashmapTemplate.h"
|
||||
B rand_subset_c2(B t, B w, B x) {
|
||||
i32 wi = o2i(w);
|
||||
i32 xi = o2i(x);
|
||||
if (RARE(wi<0)) thrM("(rand).Subset: 𝕨 cannot be negative");
|
||||
if (RARE(xi<0)) thrM("(rand).Subset: 𝕩 cannot be negative");
|
||||
if (RARE(wi>xi)) thrM("(rand).Subset: 𝕨 cannot exceed 𝕩");
|
||||
if (wi==0) return emptyIVec();
|
||||
RAND_START;
|
||||
i32* rp; B r = m_i32arrv(&rp, wi);
|
||||
i64 sz = 1;
|
||||
while (sz < wi*2) sz*= 2;
|
||||
sz*= 2;
|
||||
H_i2i* map = m_i2i(sz);
|
||||
for (i64 i = 0; i < wi; i++) rp[i] = i;
|
||||
for (i64 i = 0; i < wi; i++) {
|
||||
i32 j = wy2u0k(wyrand(&seed), xi-i) + i;
|
||||
if (j<wi) {
|
||||
i32 c = rp[j];
|
||||
rp[j] = rp[i];
|
||||
rp[i] = c;
|
||||
} else {
|
||||
rp[i] = swap_i2i(&map, j, rp[i], j);
|
||||
}
|
||||
}
|
||||
free_i2i(map);
|
||||
RAND_END;
|
||||
return r;
|
||||
}
|
||||
|
||||
static NOINLINE void rand_init() {
|
||||
rand_ns = bqn_exec(m_str32(U"{a←𝕨⋄b←𝕩⋄range⇐0}"), emptyCVec(), emptySVec()); gc_add(rand_ns);
|
||||
rand_rangeName = m_str32(U"range"); gc_add(rand_rangeName);
|
||||
rand_rangeDesc = registerNFn(m_str32(U"(rand).Range"), rand_range_c1, rand_range_c2);
|
||||
rand_ns = bqn_exec(m_str32(U"{a←𝕨⋄b←𝕩⋄range⇐0⋄deal⇐0⋄subset⇐0}"), emptyCVec(), emptySVec()); gc_add(rand_ns);
|
||||
rand_rangeName = m_str32(U"range"); gc_add(rand_rangeName); rand_rangeDesc = registerNFn(m_str32(U"(rand).Range"), rand_range_c1, rand_range_c2);
|
||||
rand_dealName = m_str32(U"deal"); gc_add(rand_dealName); rand_dealDesc = registerNFn(m_str32(U"(rand).Deal"), rand_deal_c1, rand_deal_c2);
|
||||
rand_subsetName = m_str32(U"subset"); gc_add(rand_subsetName); rand_subsetDesc = registerNFn(m_str32(U"(rand).Subset"), c1_invalid, rand_subset_c2);
|
||||
B tmp = c2(rand_ns, m_f64(0), m_f64(0));
|
||||
rand_a = ns_pos(tmp, m_str32(U"a"));
|
||||
rand_b = ns_pos(tmp, m_str32(U"b"));
|
||||
@ -248,7 +331,9 @@ B makeRand_c1(B t, B x) {
|
||||
if (!isNum(x)) thrM("•MakeRand: 𝕩 must be a number");
|
||||
if (rand_ns.u==0) rand_init();
|
||||
B r = c2(rand_ns, b(x.u>>32), b(x.u&0xFFFFFFFF));
|
||||
ns_set(r, rand_rangeName, m_nfn(rand_rangeDesc, inc(r)));
|
||||
ns_set(r, rand_rangeName, m_nfn(rand_rangeDesc, inc(r)));
|
||||
ns_set(r, rand_dealName, m_nfn(rand_dealDesc, inc(r)));
|
||||
ns_set(r, rand_subsetName, m_nfn(rand_subsetDesc, inc(r)));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
2
src/h.h
2
src/h.h
@ -190,7 +190,7 @@ typedef struct Value {
|
||||
i32 refc; // plain old reference count
|
||||
u8 mmInfo; // bucket size, mark&sweep bits when that's needed; currently unused
|
||||
u8 flags; // is sorted/a permutation/whatever in the future, currently primitive index for self-hosted runtime
|
||||
u8 type; // access into TypeInfo among generally knowing what type of object this is
|
||||
u8 type; // access into ti_*, among generally knowing what type of object this is
|
||||
ur extra; // whatever object-specific stuff. Rank for arrays, id for functions
|
||||
#ifdef OBJ_COUNTER
|
||||
u64 uid;
|
||||
|
||||
@ -91,7 +91,7 @@ static inline bool N(has) (Map* m, KT k) {
|
||||
#endif
|
||||
|
||||
|
||||
static inline void N(qins) (Map* m, u64 h1, HT h2, KT k IFVAL(, VT v)) { // if guaranteed that k doesn't exist in the map yet and there's space for this
|
||||
static inline void N(qins) (Map* m, u64 h1, HT h2 IFKEY(, KT k) IFVAL(, VT v)) { // if guaranteed that k doesn't exist in the map yet and there's space for this
|
||||
u64 mask = m->mask;
|
||||
u64 p = h1 & mask;
|
||||
while (true) {
|
||||
@ -112,7 +112,7 @@ static void N(dbl) (Map** m) {
|
||||
Map* nm = N(m)(psz*2);
|
||||
for (u64 i = 0; i < psz; i++) {
|
||||
Ent e = pm->a[i];
|
||||
if(!EMPTY(e.hash, e.key)) N(qins)(nm, H1R(e.key, e.hash), e.hash, e.key IFVAL(, e.val));
|
||||
if(!EMPTY(e.hash, e.key)) N(qins)(nm, H1R(e.key, e.hash), e.hash IFKEY(, e.key) IFVAL(, e.val));
|
||||
}
|
||||
mm_free((Value*)pm);
|
||||
*m = nm;
|
||||
@ -136,6 +136,15 @@ static inline bool N(ins) (Map** mp, KT k IFVAL(, VT v)) { // returns whether el
|
||||
IFVAL((*mp)->a[p].val = v);
|
||||
return had;
|
||||
}
|
||||
#ifdef VALS
|
||||
static inline VT N(swap) (Map** mp, KT k, VT v, VT def) { // returns either previous element or def; sets new element to v
|
||||
bool had;
|
||||
u64 p = N(mk)(mp, k, &had);
|
||||
VT prev = (*mp)->a[p].val;
|
||||
(*mp)->a[p].val = v;
|
||||
return had? prev : def;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef IFKEY
|
||||
@ -146,6 +155,7 @@ static inline bool N(ins) (Map** mp, KT k IFVAL(, VT v)) { // returns whether el
|
||||
#undef HT
|
||||
#undef KT
|
||||
#undef H1
|
||||
#undef H1R
|
||||
#undef H2
|
||||
#undef EMPTY
|
||||
#undef HDEF
|
||||
|
||||
Loading…
Reference in New Issue
Block a user