Creating buckets of letters with equal probability

Next task: deciding whether a word will be a monster, a weapon, an armor etc.

I want to do this by picking the middle character of a word, and then, depending on that character, decide which kind of dungeon entity it will be. Therefore let's create a fixed number of buckets, one or two per kind, and assign letters to each bucket so that each bucket contains letters of the same overall likelihood to appear in the English language.

Sounds complicated? Not for ChatGPT. First I let it come up with the letter probabilities:

Now I need a constant array that contains the letter probabilities of the english language - the first element the probability of an "a", the 25th the one of a "z". Can you create this in JS?

Output:

const letterProbabilities = [
  0.0817, // a
  0.0149, // b
  0.0278, // c
  0.0425, // d
  0.1270, // e
  0.0223, // f
  0.0202, // g
  0.0609, // h
  0.0697, // i
  0.0015, // j
  0.0077, // k
  0.0403, // l
  0.0241, // m
  0.0675, // n
  0.0751, // o
  0.0193, // p
  0.0010, // q
  0.0599, // r
  0.0633, // s
  0.0906, // t
  0.0276, // u
  0.0098, // v
  0.0236, // w
  0.0015, // x
  0.0197, // y
  0.0007, // z
];


Then here my "requirement". I was sure this would overwhelm it.

now it's getting complicated. Based on letterProbabilities, I need a function that you pass a number n, and the function will create n buckets of letters. If you sum the letterProbabilities of the letters in each bucket, they are nearly same. Can you do that?

 

And it's reply in all its wonderful detail incl. text:

Sure! To create n buckets of letters that have nearly the same sum of probabilities, we can use a greedy algorithm that sorts the letter probabilities in descending order and assigns each letter to the bucket with the smallest current sum.

Here's a function bucketLetters(n, letterProbabilities) that takes a number n and an array of letter probabilities letterProbabilities, and returns an array of n arrays, where each inner array contains the letters assigned to that bucket:

 

function bucketLetters(n, letterProbabilities) {
  // Sort the letter probabilities in descending order
  const sortedLetterProbabilities = [...letterProbabilities].sort((a, b) => b - a);

  // Create n empty buckets
  const buckets = Array.from({ length: n }, () => []);

  // Assign each letter to the bucket with the smallest current sum
  sortedLetterProbabilities.forEach((probability, letterIndex) => {
    let smallestBucketIndex = 0;
    let smallestBucketSum = sumArray(buckets[0].map((letterIndex) => letterProbabilities[letterIndex]));

    for (let i = 1; i < n; i++) {
      const bucketSum = sumArray(buckets[i].map((letterIndex) => letterProbabilities[letterIndex]));
      if (bucketSum < smallestBucketSum) {
        smallestBucketIndex = i;
        smallestBucketSum = bucketSum;
      }
    }

    buckets[smallestBucketIndex].push(letterIndex);
  });

  // Convert the letter indexes to letters and return the buckets
  return buckets.map((bucket) => bucket.map((letterIndex) => String.fromCharCode(letterIndex + 97)));
}

function sumArray(array) {
  return array.reduce((sum, value) => sum + value, 0);
}

 

Here's how you can use this function to create 5 buckets of letters:

const n = 5;
const buckets = bucketLetters(n, letterProbabilities);
console.log(buckets);

 

This will output an array of 5 arrays, where each inner array contains the letters assigned to that bucket. The letters are represented as strings. Note that the sum of probabilities in each bucket may not be exactly the same, but they should be very close.

 

I then let ChatGPT generate a test HTML page for it and voila it did what it was supposed to do. In the first attempt. No bug, no nothing. Here's a screenshot of the output.




Kommentare

Beliebte Posts aus diesem Blog

ChatGPT as a teacher

How it started...

Pathfinding and A*