Skip to content

Instantly share code, notes, and snippets.

@mashumafi
Created July 10, 2018 21:30
Show Gist options
  • Save mashumafi/de528aeb367e80fd590ef08c30e75072 to your computer and use it in GitHub Desktop.
Save mashumafi/de528aeb367e80fd590ef08c30e75072 to your computer and use it in GitHub Desktop.
Choose a random words based on weights
import java.util.AbstractCollection;
import java.util.Iterator;
import java.util.Random;
import java.util.Vector;
public class RandomWord {
public static void main(String []args){
Vector<Item<String>> words = new Vector<Item<String>>();
words.add(new Item<String>("Hello", 3));
words.add(new Item<String>("World", 1));
words.add(new Item<String>("Mouse", 2));
words.add(new Item<String>("Cat", 4));
words.add(new Item<String>("Dog", 8));
test(words, 0, "Hello");
test(words, 1, "Hello");
test(words, 2, "Hello");
test(words, 3, "World");
test(words, 4, "Mouse");
test(words, 5, "Mouse");
test(words, 6, "Cat");
test(words, 7, "Cat");
test(words, 8, "Cat");
test(words, 9, "Cat");
test(words, 10, "Dog");
test(words, 11, "Dog");
test(words, 12, "Dog");
test(words, 13, "Dog");
test(words, 14, "Dog");
test(words, 15, "Dog");
test(words, 16, "Dog");
test(words, 17, "Dog");
String word = ItemChooser.choose(words);
System.out.println("Your random word is: " + word);
}
static void test(AbstractCollection<Item<String>> collection, int num, String expect) {
String word = ItemChooser.choose(collection, new FixedNumberGenerator(num));
if(word != expect) {
System.out.println("Item at " + num + " is not " + expect);
}
}
}
class Item<T> {
public Item(T value, int weight) {
this.value = value;
this.weight = weight;
}
public T value;
public int weight;
}
class ItemChooser {
public static <T> T choose(AbstractCollection<Item<T>> collection, NumberGenerator generator) {
// Step 1: Calculate the weight
Iterator<Item<T>> iter = collection.iterator();
int totalWeight = 0;
while(iter.hasNext()) {
totalWeight += iter.next().weight;
}
// Step 2: Calculate random number based on totalWeight
int selectedWeight = generator.nextInt() % totalWeight;
// Step 3: Choose the word based on selectedWeight
iter = collection.iterator();
int sumWeight = 0;
Item<T> selected = null;
while(iter.hasNext()) {
selected = iter.next();
sumWeight += selected.weight;
if(selectedWeight < sumWeight) {
break;
}
}
return selected.value;
}
public static <T> T choose(AbstractCollection<Item<T>> collection) {
return choose(collection, new RandomNumberGenerator());
}
}
interface NumberGenerator {
int nextInt();
}
class RandomNumberGenerator implements NumberGenerator {
Random generator = new Random();
public int nextInt() {
return generator.nextInt();
}
}
class FixedNumberGenerator implements NumberGenerator {
int num;
FixedNumberGenerator(int num) {
this.num = num;
}
public int nextInt() {
return num;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment