Mad Lib

Challenge

Generate random stories from tuples of (noun, verb, adjective, adverb).

Solution

To generate stories, we can start with a template and fill in the blanks. For instance, when provided with the template

template = "Do you {verb} your {adjective} {noun} {adverb}? That's hilarious!";

and the values noun="dog", verb="walk", adjective="blue", adverb="quickly", the resulting story is

Do you walk your blue dog quickly? That's hilarious!

The missing pieces are the lists of words and a method for selecting words from them. Here are my lists of not-so-funny-but-safe words:

const NOUNS: &[&str] = &["dog", "cat", "elephant", "goldfish", "python"];
const VERBS: &[&str] = &["walk", "touch", "kiss", "run", "feed"];
const ADJECTIVES: &[&str] = &["blue", "hot", "cool", "soft", "hard", "dry", "wet"];
const ADVERBS: &[&str] = &["quickly", "lazily", "happily", "hungrily"];

Below is a function for drawing a random word from a list. Notice the parameter 'a indicating the lifetime of the borrowed return value.

fn random_choice<'a>(choices: &[&'a str], rng: &mut ThreadRng) -> &'a str {
    choices.choose(rng).unwrap()
}

With all the elements in place, we can wire up the final solution:

fn main() {
    let mut rng = rand::thread_rng();
    let noun = random_choice(NOUNS, &mut rng);
    let verb = random_choice(VERBS, &mut rng);
    let adjective = random_choice(ADJECTIVES, &mut rng);
    let adverb = random_choice(ADVERBS, &mut rng);

    println!(
        "Do you {} your {} {} {}? That's hilarious!",
        verb, adjective, noun, adverb
    );
}

Some sample outputs:

Do you touch your wet elephant quickly? That's hilarious!
Do you feed your cool cat hungrily? That's hilarious!
Do you walk your soft goldfish quickly? That's hilarious!

With the presented word lists, how many distinct stories are there? According to the rule of product, the answer is

$$ |nouns| \times |verbs| \times |adjectives| \times |adverbs| = 5 \times 5 \times 7 \times 4
= 700 $$

where |S| denotes the number of elements of in a set S.