This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

142
Task/Mad-Libs/0DESCRIPTION Normal file
View file

@ -0,0 +1,142 @@
[[wp:Mad Libs|Mad Libs]] is a phrasal template word game where one player prompts another for a list of words to substitute for blanks in a story, usually with funny results.
Write a program to create a Mad Libs like story. The program should 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:
<pre>
<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.
</pre>
It should then ask for a <tt>name</tt>, a <tt>he or she</tt> and a <tt>noun</tt> (<tt><nowiki><name></nowiki></tt> gets replaced both times with the same value.)
{{wikipedia}}
== {{header|Ada}} ==
The fun of Mad Libs is not knowing the story ahead of time, so the program reads the story template from a text file. The name of the text file is given as a command line argument.
<lang Ada>with Ada.Text_IO, Ada.Command_Line, String_Helper;
procedure Madlib is
use String_Helper;
Text: Vector := Get_Vector(Ada.Command_Line.Argument(1));
M, N: Natural;
begin
-- search for templates and modify the text accordingly
for I in Text.First_Index .. Text.Last_Index loop
loop
Search_Brackets(Text.Element(I), "<", ">", M, N);
exit when M=0; -- "M=0" means "not found"
Ada.Text_IO.Put_Line("Replacement for " & Text.Element(I)(M .. N) & "?");
declare
Old: String := Text.Element(I)(M .. N);
New_Word: String := Ada.Text_IO.Get_Line;
begin
for J in I .. Text.Last_Index loop
Text.Replace_Element(J, Replace(Text.Element(J), Old, New_Word));
end loop;
end;
end loop;
end loop;
-- write the text
for I in Text.First_Index .. Text.Last_Index loop
Ada.Text_IO.Put_Line(Text.Element(I));
end loop;
end Madlib;</lang>
It uses an auxiliary package String_Helper for simple string functions;
<lang Ada>with Ada.Containers.Indefinite_Vectors;
package String_Helper is
function Index(Source: String; Pattern: String) return Natural;
procedure Search_Brackets(Source: String;
Left_Bracket: String;
Right_Bracket: String;
First, Last: out Natural);
-- returns indices of first pair of brackets in source
-- indices are zero if no such brackets are found
function Replace(Source: String; Old_Word: String; New_Word: String)
return String;
package String_Vec is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive,
Element_Type => String);
type Vector is new String_Vec.Vector with null record;
function Get_Vector(Filename: String) return Vector;
end String_Helper;</lang>
Here is the implementation of String_Helper:
<lang Ada>with Ada.Strings.Fixed, Ada.Text_IO;
package body String_Helper is
function Index(Source: String; Pattern: String) return Natural is
begin
return Ada.Strings.Fixed.Index(Source => Source, Pattern => Pattern);
end Index;
procedure Search_Brackets(Source: String;
Left_Bracket: String;
Right_Bracket: String;
First, Last: out Natural) is
begin
First := Index(Source, Left_Bracket);
if First = 0 then
Last := 0; -- not found
else
Last := Index(Source(First+1 .. Source'Last), Right_Bracket);
if Last = 0 then
First := 0; -- not found;
end if;
end if;
end Search_Brackets;
function Replace(Source: String; Old_Word: String; New_Word: String)
return String is
L: Positive := Old_Word'Length;
I: Natural := Index(Source, Old_Word);
begin
if I = 0 then
return Source;
else
return Source(Source'First .. I-1) & New_Word
& Replace(Source(I+L .. Source'Last), Old_Word, New_Word);
end if;
end Replace;
function Get_Vector(Filename: String) return Vector is
F: Ada.Text_IO.File_Type;
T: Vector;
begin
Ada.Text_IO.Open(F, Ada.Text_IO.In_File, Filename);
while not Ada.Text_IO.End_Of_File(F) loop
T.Append(Ada.Text_IO.Get_Line(F));
end loop;
Ada.Text_IO.Close(F);
return T;
end Get_Vector;
end String_Helper;</lang>
A sample run (with the story template in t.txt):
<pre>./madlib t.txt
Replacement for <name>?
Hilla, the hypohondraic,
Replacement for <he or she>?
She
Replacement for <noun>?
headache
Hilla, the hypohondraic, went for a walk in the park. She
found a headache. Hilla, the hypohondraic, decided to take it home.</pre>

View file

@ -0,0 +1,13 @@
FileSelectFile, filename, , %A_ScriptDir%, Select a Mad Libs template, *.txt
If ErrorLevel
ExitApp ; the user canceled the file selection
FileRead, contents, %filename%
pos := match := 0
While pos := RegExMatch(contents, "<[^>]+>", match, pos+strLen(match))
{
InputBox, repl, Mad Libs, Enter a replacement for %match%:
If ErrorLevel ; cancelled inputbox
ExitApp
StringReplace, contents, contents, %match%, %repl%, All
}
MsgBox % contents

View file

@ -0,0 +1,48 @@
#include <iostream>
#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;
}

View file

@ -0,0 +1,20 @@
import std.stdio, std.regex, std.algorithm, std.string, std.array;
void main() {
writeln("Enter a story template, terminated by an empty line:");
string story;
while (true) {
auto line = stdin.readln().strip();
if (line.empty) break;
story ~= line ~ "\n";
}
auto re = regex("<.+?>", "g");
auto fields = story.match(re).map!q{a.hit}().array().sort().uniq();
foreach (field; fields) {
writef("Enter a value for '%s': ", field[1 .. $ - 1]);
story = story.replace(field, stdin.readln().strip());
}
writeln("\nThe story becomes:\n", story);
}

View file

@ -0,0 +1,53 @@
-module(madlib).
-compile(export_all).
main() ->
main([]).
main([]) ->
madlib(standard_io);
main([File]) ->
{ok, F} = file:open(File,read),
madlib(F).
madlib(Device) ->
{Dict, Lines} = parse(Device),
Substitutions = prompt(Dict),
print(Substitutions, Lines).
prompt(Dict) ->
Keys = dict:fetch_keys(Dict),
lists:foldl(fun (K,D) ->
S = io:get_line(io_lib:format("Please name a ~s: ",[K])),
dict:store(K, lists:reverse(tl(lists:reverse(S))), D)
end, Dict, Keys).
print(Dict,Lines) ->
lists:foreach(fun (Line) ->
io:format("~s",[substitute(Dict,Line)])
end, Lines).
substitute(Dict,Line) ->
Keys = dict:fetch_keys(Dict),
lists:foldl(fun (K,L) ->
re:replace(L,K,dict:fetch(K,Dict),[global,{return,list}])
end, Line, Keys).
parse(Device) ->
parse(Device, dict:new(),[]).
parse(Device, Dict,Lines) ->
case io:get_line(Device,"") of
eof ->
{Dict, lists:reverse(Lines)};
"\n" ->
{Dict, lists:reverse(Lines)};
Line ->
parse(Device, parse_line(Dict, Line), [Line|Lines])
end.
parse_line(Dict, Line) ->
{match,Matches} = re:run(Line,"<.*?>",[global,{capture,[0],list}]),
lists:foldl(fun ([M],D) ->
dict:store(M,"",D)
end, Dict, Matches).

View file

@ -0,0 +1,7 @@
68> madlib:main("test.mad").
Please name a <noun>: banana
Please name a <name>: Jack
Please name a <he or she>: She
Jack went for a walk in the park. She
found a banana. Jack decided to take it home.ok
69>

View file

@ -0,0 +1,57 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"log"
"os"
"regexp"
"strings"
)
func main() {
pat := regexp.MustCompile("<.+?>")
if len(os.Args) != 2 {
fmt.Println("usage: madlib <story template file>")
return
}
b, err := ioutil.ReadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
tmpl := string(b)
s := []string{} // patterns in order of appearance
m := map[string]string{} // mapping from patterns to replacements
for _, p := range pat.FindAllString(tmpl, -1) {
if _, ok := m[p]; !ok {
m[p] = ""
s = append(s, p)
}
}
fmt.Println("Enter replacements:")
br := bufio.NewReader(os.Stdin)
for _, p := range s {
for {
fmt.Printf("%s: ", p[1:len(p)-1])
r, isPre, err := br.ReadLine()
if err != nil {
log.Fatal(err)
}
if isPre {
log.Fatal("you're not playing right. :P")
}
s := strings.TrimSpace(string(r))
if s == "" {
fmt.Println(" hmm?")
continue
}
m[p] = s
break
}
}
fmt.Println("\nYour story:\n")
fmt.Println(pat.ReplaceAllStringFunc(tmpl, func(p string) string {
return m[p]
}))
}

View file

@ -0,0 +1,16 @@
procedure main()
ml := "<name> went for a walk in the park. There <he or she> _
found a <noun>. <name> decided to take it home." # sample
MadLib(ml) # run it
end
link strings
procedure MadLib(story)
write("Please provide words for the following:")
V := []
story ? while ( tab(upto('<')), put(V,tab(upto('>')+1)) )
every writes(v := !set(V)," : ") do
story := replace(story,v,read())
write("\nYour MadLib follows:\n",story)
end

View file

@ -0,0 +1,13 @@
temp$="<name> went for a walk in the park. <he or she> found a <noun>. <name> decided to take it home."
k = instr(temp$,"<")
while k
replace$ = mid$(temp$,k,instr(temp$,">")-k + 1)
print "Replace:";replace$;" with:"; :input with$
while k
temp$ = left$(temp$,k-1) + with$ + mid$(temp$,k + len(replace$))
k = instr(temp$,replace$,k)
wend
k = instr(temp$,"<")
wend
print temp$
wait

View file

@ -0,0 +1,16 @@
(de madlib (Template)
(setq Template (split (chop Template) "<" ">"))
(let (Reps () Text ())
(while Template
(push 'Text (pop 'Template))
(let? Rep (mapcar pack (split (pop 'Template) ":"))
(if (assoc (car Rep) Reps)
(push 'Text (cdr @))
(until (and
(prin "Gimme a(n) " (or (cadr Rep) (car Rep)) ": ")
(clip (in NIL (line)))
(push 'Text @)
(push 'Reps (cons (car Rep) @)) )
(prinl "Huh? I got nothing.") ) ) ) )
(prinl (need 30 '-))
(prinl (flip Text)) ) )

View file

@ -0,0 +1,20 @@
import re
# Optional Python 2.x compatibility
#try: input = raw_input
#except: pass
template = '''<name> went for a walk in the park. <he or she>
found a <noun>. <name> decided to take it home.'''
def madlibs(template):
print('The story template is:\n' + template)
fields = sorted(set( re.findall('<[^>]+>', template) ))
values = input('\nInput a comma-separated list of words to replace the following items'
'\n %s: ' % ','.join(fields)).split(',')
story = template
for f,v in zip(fields, values):
story = story.replace(f, v)
print('\nThe story becomes:\n\n' + story)
madlibs(template)

View file

@ -0,0 +1,36 @@
/*REXX program to prompt user for template substitutions within a story.*/
@.=; !.=0; #=0; @= /*assign some defaults. */
parse arg iFID . /*allow use to specify input file*/
if iFID=='' then iFID="MAD_LIBS.TXT" /*Not specified? Then use default*/
do recs=1 while lines(iFID)\==0 /*read the input file 'til done. */
@.recs=linein(iFID); @=@ @.recs /*read a record, append it to @ */
if @.recs='' then leave /*Read a blank line? We're done.*/
end /*recs*/
recs=recs-1 /*adjust for E─O─F or blank line.*/
do forever /*look for templates in the text.*/
parse var @ '<' ? '>' @ /*scan for <ααα> stuff in text.*/
if ?='' then leave /*if no ααα, then we're done. */
if !.? then iterate /*already asked? Keep scanning.*/
!.?=1 /*mark this ααα as "found". */
do forever /*prompt user for a replacement. */
say ' please enter a word or phrase to replace: ' ?
parse pull ans; if ans\='' then leave
end /*forever*/
#=#+1 /*bump the template counter. */
old.# = '<'?">"; new.# = ans /*assign "old" name & "new" name.*/
end /*forever*/
say; say copies('',79) /*display a blank and a fence. */
do m=1 for recs /*display the text, line for line*/
do n=1 for # /*perform substitutions in text. */
@.m = changestr(old.n, @.m, new.n)
end /*n*/
say @.m /*display (new) substituted text.*/
end /*m*/
say copies('',79) /*display a final (output) fence.*/
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,13 @@
puts "Enter a story, terminated by an empty line:"
story = ""
until (line = STDIN.gets).chomp.empty?
story << line
end
story.scan(/(?<=[<]).+?(?=[>])/).uniq.each do |var|
print "Enter a value for '#{var}': "
story.gsub!(/<#{var}>/, STDIN.gets.chomp)
end
puts ""
puts story

View file

@ -0,0 +1,23 @@
package require Tcl 8.5
# Read the template...
puts [string repeat "-" 70]
puts "Enter the story template, ending with a blank line"
while {[gets stdin line] > 0} {
append content $line "\n"
}
# Read the mapping...
puts [string repeat "-" 70]
set mapping {}
foreach piece [regexp -all -inline {<[^>]+>} $content] {
if {[dict exists $mapping $piece]} continue
puts -nonewline "Give me a $piece: "
flush stdout
dict set mapping $piece [gets stdin]
}
# Apply the mapping and print...
puts [string repeat "-" 70]
puts -nonewline [string map $mapping $content]
puts [string repeat "-" 70]