NIALL Perl

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;
}