npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

uniform-probability-selector

v0.1.7

Published

Ensuring uniform randomness when generating something using a recursive process.

Downloads

11

Readme

Uniform Probability Selector

Module for making equally random selections of items that are arranged in a tree structure. It contains two classes described blow.

Classes

SelectionNode

Abstract class that contains logic for uniformly random selection

Here is a stupid but simple example. Suppose that we are storing the names of students separately in categories. We want a data structure that would allow us to select any one student at random.

import { SelectionNode } from "uniform-probability-selector";

class StudentSelector extends SelectionNode<string, Array<string>> {
  /**
   * Define your recusive selection logic here.
   *    Arguments:
   *        snippet: Data returned from a child node (or null if this is a leaf node)
   *        childIndexUsed: Index of the child node from which the snippet was returned. (null if this is a leaf node)
   *
   *    Returns whatever value that you want this node to return
   */
  recursiveSelection(snippet: string, _childIndexUsed: number): string {
    /**
     * Case n=1
     * If snippet is null, then this is a leaf node.
     * So just return the value of that you want a leaf to generate.
     * In this example, we want to return a randomly selected students' name.
     */
    if (snippet === null) {
      const randomIndex = Math.floor(Math.random() * this.data!.length);
      return this.data![randomIndex];
    }

    /**
     * Case n>1: snippet is output from n-1th step.
     * If this is not a leaf node, do whatever function you want the intermediary
     * nodes to do with the given snippet.
     * In this example, the intermediary node simply returns the snippet as is.
     */
    return snippet;
  }

  /**
   * Set how you want the weights of your nodes to be computed.
   * To achieve a uniform distribution, you should make the weight of a node to be the number
   * unique values that can be generated from it (and its descendants).
   *
   * Returns a number.
   */
  computeWeight(): number {
    // If this is a leaf, just return the number of names.
    if (this.isLeaf()) {
      return this.data!.length;
    }
    // Otherwise, just add up the weights of all the child nodes.
    return this.getSumOfChildWeights();
  }
}

const artStudents = new StudentSelector(["joe", "jill"]);
const musicStudents = new StudentSelector(["albert", "alice", "alex"]);
const allStudents = new StudentSelector();
allStudents.addChild(artStudents);
allStudents.addChild(musicStudents);

// Get any one of the art students at random
console.log(`${artStudents.makeRandomSelection()} does art`);

// Get any one of the music students at random
console.log(`${musicStudents.makeRandomSelection()} does music`);

// Make a uniformly random selection from all students
console.log(`${allStudents.makeRandomSelection()} is a student`);

// Print number of students under any node
console.log("Number of music students", musicStudents.getWeight()); // 3
console.log("Total number of students", allStudents.getWeight()); // 5

TextBuilderNode

Implementation of SelectionNode for constructing texts out of substrings.

Here is a simple example that generates a dialogue.

import { TextBuilderNode } from "uniform-probability-selector";

const personA = new TextBuilderNode([
  "Do you... do you love me?\n",
  "I love you. Do you feel the same?\n",
  "You love me, right?\n",
  "Please, tell me you love me.\n",
]);

const personB = new TextBuilderNode([
  "No, I don't love you.",
  "Hell no.",
  "In year dreams, maybe.",
  "Of course I like you.",
  "I don't see you that way.",
  "You're... you're a good friend.",
]);

personA.addChild(personB);

// Print a randomly selected dialogue
console.log(personA.makeRandomSelection());
// "Do you... do you love me?"
//   "Of course I like you."