2016-07-04 21:39:14 +02:00
|
|
|
package MarkovBot::MarkovChain;
|
|
|
|
use base qw(Exporter);
|
|
|
|
use 5.010;
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
our @EXPORT = qw(markov);
|
|
|
|
|
|
|
|
use FindBin qw($Bin);
|
|
|
|
use lib $Bin;
|
|
|
|
|
|
|
|
use MarkovBot::Config;
|
|
|
|
use MarkovBot::Redis;
|
2016-07-04 22:32:37 +02:00
|
|
|
use Encode qw(decode encode);
|
2016-07-19 15:14:11 +02:00
|
|
|
use if (config("rng") eq "mt"), "Math::Random::MT::Perl" => qw(rand);
|
2016-07-04 21:39:14 +02:00
|
|
|
|
|
|
|
sub markov( $ ) {
|
|
|
|
# markov - given two starting words, returns a markov chain result
|
|
|
|
|
|
|
|
my $redis = redis;
|
|
|
|
my $p = config "redis_prefix";
|
2016-07-04 22:32:37 +02:00
|
|
|
|
2016-07-04 21:39:14 +02:00
|
|
|
my $s = shift;
|
|
|
|
my @s = @{$s};
|
2016-07-04 22:32:37 +02:00
|
|
|
@s = map {encode("UTF-8", $_)} @s;
|
2016-07-04 21:39:14 +02:00
|
|
|
|
|
|
|
if (!$redis->llen("$p:chains:$s[0],$s[1]")) {
|
|
|
|
# Phrase is not known
|
|
|
|
return undef;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
# get next word
|
|
|
|
my $len = $redis->llen("$p:chains:$s[$#s-1],$s[$#s]");
|
|
|
|
my $pos = int(rand($len));
|
|
|
|
push @s, $redis->lrange("$p:chains:$s[$#s-1],$s[$#s]", $pos, $pos);
|
|
|
|
last if $s[$#s] eq "___end___";
|
|
|
|
}
|
|
|
|
|
|
|
|
pop @s;
|
2016-07-04 22:32:37 +02:00
|
|
|
@s = map {decode("UTF-8", $_)} @s;
|
2016-07-04 21:39:14 +02:00
|
|
|
return join " ", @s;
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|