Mad Libs: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|Pike}}: fix code to match intent as gleaned from wp:Mad Libs)
Line 62: Line 62:


=={{header|Pike}}==
=={{header|Pike}}==
this solution uses readline to make editing more convenient. it also adds an extra feature to define variables while writing, show the story written so far and continue adding to the story until exit is called.
this solution uses readline to make editing more convenient.
<lang Pike>#!/usr/bin/pike
<lang Pike>#!/usr/bin/pike
Line 73: Line 73:
Names or objects in the story can be made variable by
Names or objects in the story can be made variable by
referencing them as <person> <object>, etc.
referencing them as <person> <object>, etc.
End the story with an empty line.


Type show to read the story. You will be asked to fill the variables,
After you introduce variables you may name them as:
and the the story will be shown.
(person is called Michael)
(object is a bag)

End the story with an empty line.
If there are any undefined variables you will be reminded to name them.


Type help to see this message again.
Type help to see this message again.
Type show to see your story.
Type exit to quit.
Type exit to quit.


");
");

if (sizeof(variables))
{
write("you have used the following variables:\n");
foreach(variables; string name; string value)
{
write("%s is %s\n", name, value);
}
write("\n");
}
}
}


void add_line(string input)
void add_line(string input)
{
{
parse_for_variables(input);
array variables = parse_for_variables(input);
write("Found variables: %{\"%s\" %}\n", variables);
story += input+"\n";
story += input+"\n";
}
}


void parse_for_variables(string input)
array parse_for_variables(string input)
{
{
array vars = Array.flatten(array_sscanf(input, "%*[^<>]%{<%[^<>]>%*[^<>]%}%*[^<>]"));
array vars = Array.flatten(array_sscanf(input, "%*[^<>]%{<%[^<>]>%*[^<>]%}%*[^<>]"));
foreach(vars;; string name)
return Array.uniq(vars);
{
if (!variables[name])
{
variables["<"+name+">"]="<"+name+">";
write("Found new variable \"%s\"\n", name);
}
}
}
}


int(0..1) add_variable(string input)
mapping fill_variables(string story)
{
{
array var = array_sscanf(input, "(%s is called %s)");
array vars = parse_for_variables(story);
if (sizeof(var) != 2)
mapping variables = ([]);
foreach(vars;; string name)
var = array_sscanf(input, "(%s is a %s)");
if (sizeof(var) == 2)
if (variables["<"+var[0]+">"] == "<"+var[0]+">")
{
variables["<"+var[0]+">"] = variables[var[1]];
write("Defining %s as \"%s\"\n", var[0], var[1]);
return true;
}
return false;
}

int check_variables()
{
int new;
foreach(variables; string name; string value)
{
{
string value = readln->read(sprintf("Please name a%s %s: ", (<'a','e','i','o','u'>)[name[1]]?"":"n", name));
if (value == name)
{
if (value != "")
new++;
variables["<"+name+">"] = value;
string new_value = readln->read(sprintf("Please give a name for %s: ", name));
if (new_value != "")
variables[name] = new_value;
}
}
}
return new;
return variables;
}
}


void show_story()
void show_story(string story)
{
{
mapping variables = fill_variables(story);
check_variables();
write("\n"+replace(story, variables));
write("\n"+replace(story, variables));
}
}
Line 159: Line 121:
}
}
mapping variables = ([]);
mapping functions = ([ "help":print_help,
mapping functions = ([ "help":print_help,
"show":show_story,
"show":show_story,
Line 180: Line 141:
exit(0);
exit(0);
if(input == "")
if(input == "")
show_story();
show_story(story);
else if (functions[input])
else if (functions[input])
functions[input]();
functions[input]();
else if (!add_variable(input))
else add_line(input);
add_line(input);
}
}
}</lang>
}</lang>
Line 193: Line 153:
Names or objects in the story can be made variable by
Names or objects in the story can be made variable by
referencing them as <person> <object>, etc.
referencing them as <person> <object>, etc.
End the story with an empty line.
Type show to read the story. You will be asked to fill the variables,
After you introduce variables you may name them as:
and the the story will be shown.
(person is called Michael)
(object is a bag)
End the story with an empty line.
If there are any undefined variables you will be reminded to name them.
Type help to see this message again.
Type help to see this message again.
Type show to see your story.
Type exit to quit.
Type exit to quit.
> <person> is a programmer.
> <person> is a programmer.
Found new variable "person"
Found variables: "person"
> <he or she> created <website> for all of us to enjoy.
> <he or she> created <website> for all of us to enjoy.
Found new variable "he or she"
Found variables: "he or she" "website"
Found new variable "website"
>
>
Please give a name for <website>: RosettaCode
Please name a person: Michael
Please give a name for <he or she>: he
Please name a he or she: he
Please give a name for <person>: Michael
Please name a website: RosettaCode
Michael is a programmer.
Michael is a programmer.
he created RosettaCode for all of us to enjoy.
he created RosettaCode for all of us to enjoy.
>
Please name a person: Guilaumme
Please name a he or she: he
Please name a website: PLEAC
Guilaumme is a programmer.
he created PLEAC for all of us to enjoy.
> exit
> exit

Revision as of 09:38, 7 November 2011

Mad Libs is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Write a program to read a multiline story from the input. The story will be terminated with a blank line. Then, find each replacement to be made within the story, ask the user for a word to replace it with, and make all the replacements. Stop when there are none left and print the final story.

The input should be in the form:

<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.

It should then ask for a name, a he or she and a noun. (<name> gets replaced both times with the same value.)

C++

<lang cpp>#include <iostream>

  1. include <string>

using namespace std;

int main() {

 string story, input;
 //Loop
 while(true)
 {
   //Get a line from the user
   getline(cin, input);
   //If it's blank, break this loop
   if(input == "\r")
     break;
   //Add the line to the story
   story += input;
 }
 //While there is a '<' in the story
 int begin;
 while((begin = story.find("<")) != string::npos)
 {
   //Get the category from between '<' and '>'
   int end = story.find(">");
   string cat = story.substr(begin + 1, end - begin - 1);
   //Ask the user for a replacement
   cout << "Give me a " << cat << ": ";
   cin >> input;
   //While there's a matching category 
   //in the story
   while((begin = story.find("<" + cat + ">")) != string::npos)
   {
     //Replace it with the user's replacement
     story.replace(begin, cat.length()+2, input);
   }
 }
 //Output the final story
 cout << endl << story;
 return 0;

} </lang>

Pike

this solution uses readline to make editing more convenient. <lang Pike>#!/usr/bin/pike

Stdio.Readline readln = Stdio.Readline();

void print_help() {

   write(#"Write a Story.

Names or objects in the story can be made variable by referencing them as <person> <object>, etc. End the story with an empty line.

Type show to read the story. You will be asked to fill the variables, and the the story will be shown.

Type help to see this message again. Type exit to quit.

"); }

void add_line(string input) {

   array variables = parse_for_variables(input);
   write("Found variables: %{\"%s\" %}\n", variables);
   story += input+"\n";

}

array parse_for_variables(string input) {

   array vars = Array.flatten(array_sscanf(input, "%*[^<>]%{<%[^<>]>%*[^<>]%}%*[^<>]"));
   return Array.uniq(vars);

}

mapping fill_variables(string story) {

   array vars = parse_for_variables(story);
   mapping variables = ([]);
   foreach(vars;; string name)
   {
       string value = readln->read(sprintf("Please name a%s %s: ", (<'a','e','i','o','u'>)[name[1]]?"":"n", name));
       if (value != "")
           variables["<"+name+">"] = value;
   }
   return variables;

}

void show_story(string story) {

   mapping variables = fill_variables(story);
   write("\n"+replace(story, variables));

}

void do_exit() {

   exit(0);

}

mapping functions = ([ "help":print_help,

                      "show":show_story,
                      "exit":do_exit,
                    ]);

string story = "";

void main() {

   Stdio.Readline.History readline_history = Stdio.Readline.History(512);
   readln->enable_history(readline_history);

   string prompt="> ";

   print_help();
   while(1)
   {
       string input=readln->read(prompt);
       if(!input)
           exit(0);
       if(input == "")
           show_story(story);
       else if (functions[input])
           functions[input]();
       else add_line(input);
   }

}</lang>

Sample output:

Write a Story.

Names or objects in the story can be made variable by 
referencing them as <person> <object>, etc.
End the story with an empty line.

Type show to read the story. You will be asked to fill the variables, 
and the the story will be shown.

Type help to see this message again.
Type exit to quit.

> <person> is a programmer.
Found variables: "person" 
> <he or she> created <website> for all of us to enjoy.
Found variables: "he or she" "website" 
> 
Please name a person: Michael
Please name a he or she: he
Please name a website: RosettaCode

Michael is a programmer.
he created RosettaCode for all of us to enjoy.
> 
Please name a person: Guilaumme
Please name a he or she: he
Please name a website: PLEAC

Guilaumme is a programmer.
he created PLEAC for all of us to enjoy.
> exit