From www.yoz.com, but found in an archived email thread wouldn't you know:
(Back to the main NIALL page, then)
# non-intelligent language learner
# by Yoz, 17/1/2000
use strict;
srand(); # RANDOMISE USR 31239
my @words; # list of words in read sentence
my %dict; # keys: words
# values: anon-hashes with following word keyed to number of appearances
print "Welcome to Yoz's Non-Intelligent Language Learner!\n";
print "Please type a sentence:\n> > >";
# main input-reading loop
# reads a line, studies, then spits out a line with the randomiser
# NOTE: sentences should end in a single full stop
# anything that isn't a space is considered a word, because this is a
quickie
# and yes, I know it fucks up if there's a standalone .
# in the middle of the sentence
while (<STDIN>)
{
# study line
@words = split(/\s+/);
if (@words) # we have something to look at
{
learn(@words);
}
# now make up a new sentence
print "NIALL says: ".burble()."\n\n";
print "> > > ";
}
# read list of words, add or increment tuples in %dict
sub learn
{
my @wlist = @_;
push(@wlist,"."); # full stop = sentence ender
my $cw = "%START%"; # current word; we start the learning loop
# with the start of the sentence
my $nw; # next word
foreach $nw (@wlist)
{
${$dict{$cw}}{$nw}++;
# okay, what that did was locate cw in the main dictionary, and add 1
# to the entry for nw in the local following-word dictionary for cw
# if the entry for either nw or cw doesn't exist, it creates them
# I like perl lots
$cw = $nw;
}
}
# just go off on one with the dictionary
sub burble
{
my $cw = "%START%";
my $sentence;
my $nw;
my ($score, $s, $roll);
while ($cw ne ".") # while we're not at the end
# of the sentence yet
{
$score = 0;
# get total score to randomise within
foreach $s (values %{$dict{$cw}})
{
$score += $s;
}
# now get a random number within that
$roll = int(rand()*$score);
$score = 0;
foreach $nw (keys %{$dict{$cw}})
{
$score += ${$dict{$cw}}{$nw};
if ($score > $roll) # chosen a word
{
$sentence .= "$nw " unless $nw eq ".";
$cw = $nw;
last;
}
}
}
return $sentence;
}