From eccb20c3b7b3492fbe70648a6410b930fdb29e48 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 16 Apr 2022 23:23:15 +0100 Subject: [PATCH] Fix `choose` and add weighted `wchoose` --- packages/core/signal.mjs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index 5a0f56f2..a9f49d65 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -70,14 +70,37 @@ export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i)); export const irand = (ipat) => reify(ipat).fmap(_irand).innerJoin(); export const chooseWith = (pat, xs) => { + xs = xs.map(reify); if (xs.length == 0) { return silence; } - return pat.range(0, xs.length).fmap((i) => xs[Math.floor(i)]); + return pat.range(0, xs.length).fmap((i) => xs[Math.floor(i)]).outerJoin(); }; export const choose = (...xs) => chooseWith(rand, xs); +const _wchooseWith = function (pat, ...pairs) { + const values = pairs.map((pair) => reify(pair[0])); + const weights = []; + let accum = 0; + for (const pair of pairs) { + accum += pair[1]; + weights.push(accum); + } + const total = accum; + const match = function(r) { + const find = r * total; + return values[weights.findIndex((x) => x > find, weights)]; + }; + return pat.fmap(match); +}; + +const wchooseWith = (...args) => _wchooseWith(...args).outerJoin() + +export const wchoose = (...pairs) => wchooseWith(rand, ...pairs); + +export const wchooseCycles = (...pairs) => _wchooseWith(rand, ...pairs).innerJoin(); + export const perlinWith = (pat) => { const pata = pat.fmap(Math.floor); const patb = pat.fmap((t) => Math.floor(t) + 1);