Skip to content

Commit

Permalink
added object.choose
Browse files Browse the repository at this point in the history
  • Loading branch information
rgrannell1 committed Aug 6, 2023
1 parent 9b534c1 commit c051d7c
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
27 changes: 22 additions & 5 deletions src/object/object.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import * as Peach from "../mod.ts";

const hangulChars = Peach.String.from(
Peach.String.blocks.hangulSyllables(Peach.Number.uniform),
5,
);

Deno.test({
name: "Object.from | Runs",
fn() {
Expand All @@ -17,3 +12,25 @@ Deno.test({
gen();
},
});

Deno.test({
name: "Object.choose | preserves elements",
fn() {
const objects = Peach.Object.from(
Peach.String.letters(Peach.Number.uniform),
() => 0,
10
)

for (let idx = 0; idx < 1_000; idx++) {
const sample = objects();

const elements = Object.values(sample);
elements.forEach((element) => {
if (element !== 0) {
throw new Error("Element was not preserved");
}
});
}
}
})
37 changes: 35 additions & 2 deletions src/object/object.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Thunk, Wrapped } from "../types.ts";
import type { Thunk, Wrapped, Key, DensityBigInt } from "../types.ts";
import { unwrap } from "../types.ts";

/**
Expand All @@ -12,7 +12,7 @@ import { unwrap } from "../types.ts";
* that size is an upper-limit; if key yields duplicate values, the resulting object will have fewer
* properties
*/
export function from<K extends string | number | symbol, V>(
export function from<K extends Key, V>(
key: Wrapped<K>,
val: Wrapped<V>,
size: Wrapped<number>,
Expand All @@ -28,3 +28,36 @@ export function from<K extends string | number | symbol, V>(
return record;
};
}


/*
* Given a object of keys: fuzzers, and a density function, retrieve a subset of elements
*
* @param elems A object of keys: fuzzers
* @param density A function that takes a min and max, and returns a BigInt
*
* @returns A thunk that returns a subset of the umwrapped fuzzers
*/
export function choose<K extends Key, V>(obj: Wrapped<Record<K, V>>, density: DensityBigInt) {
return () => {
const concreteElems = Object.entries(unwrap(obj)) as [K, V][];
const subsetCount = BigInt(2) ^ BigInt(concreteElems.length);
const index = unwrap(density(BigInt(0), subsetCount));

// bits correspond to a include-or-don't for each element
const bits = index
.toString(2)
.padStart(concreteElems.length, "0")
.split("");

const subset: [K, V][] = [];

for (let idx = 0; idx < bits.length; idx++) {
if (bits[idx] === "1") {
subset.push(concreteElems[idx]);
}
}

return Object.fromEntries(subset);
}
}
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export type DensityBigInt = (
to: Wrapped<bigint>,
) => Wrapped<bigint>;

export type Key = string | number | symbol;

export type StateMachineResult<T> = {
state: string;
value: T;
Expand Down

0 comments on commit c051d7c

Please sign in to comment.