-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmarkov.d
58 lines (55 loc) · 1.61 KB
/
markov.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/+
+ markov.d
+ a program to create random sentences from
+ a sample text file using markov chains
+/
import std.file;
import std.random;
import std.stdio;
import std.string;
import std.conv;
void main(string[] argv)
{
if (argv.length < 3)
{
writeln("Usage: " ~ argv[0] ~ "[file] [key size] [output size]");
return;
}
auto filename = argv[1];
auto words = (cast(string) read(filename)).split;
int keySize = to!int(argv[2]);
int outputLength = to!int(argv[3]);
// Construct the dictionary
string[][string] dict;
foreach (i; 0 .. words.length-keySize)
{
// Extract the word after the current key
auto wordIndex = i + keySize;
auto key = words[i .. wordIndex].join(" ");
auto value = words[wordIndex];
if (key in dict)
dict[key] ~= value;
else
dict[key] = [value];
}
dict = dict.rehash;
// Construct a new sentence using the dictionary.
// Start with a random keySize word long phrase
auto prefix = dict.keys.choice.split;
auto output = prefix;
foreach (i; 0 .. outputLength)
{
auto key = prefix.join(" ");
if (key !in dict || prefix.length == 0)
break;
// Pick a random successor of the phrase
// and add it to the output
auto newWord = dict[key].choice;
output ~= newWord;
// Set the new key phrase to the phrase
// with the first word removed and the successor
// added.
prefix = prefix[1 .. $] ~ newWord;
}
output.join(" ").writeln;
}