-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMarkov.cs
More file actions
73 lines (65 loc) · 2.42 KB
/
Markov.cs
File metadata and controls
73 lines (65 loc) · 2.42 KB
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace NoMoreBotrooms
{
public class Markov
{
static string Join(string a, string b) {
return a + " " + b;
}
public static string MarkovChain(string filePath, int keySize, int outputSize) {
if (keySize < 1) throw new ArgumentException("Key size can't be less than 1");
string body;
using (StreamReader sr = new StreamReader(filePath)) {
body = sr.ReadToEnd();
}
var words = body.Split();
if (outputSize < keySize || words.Length < outputSize) {
throw new ArgumentException("Output size is out of range");
}
Dictionary<string, List<string>> dict = new Dictionary<string, List<string>>();
for (int i = 0; i < words.Length - keySize; i++) {
var key = words.Skip(i).Take(keySize).Aggregate(Join);
string value;
if (i + keySize < words.Length) {
value = words[i + keySize];
} else {
value = "";
}
if (dict.ContainsKey(key)) {
dict[key].Add(value);
} else {
dict.Add(key, new List<string>() { value });
}
}
Random rand = new Random();
List<string> output = new List<string>();
int n = 0;
int rn = rand.Next(dict.Count);
string prefix = dict.Keys.Skip(rn).Take(1).Single();
output.AddRange(prefix.Split());
while (true) {
var suffix = dict[prefix];
if (suffix.Count == 1) {
if (suffix[0] == "") {
return output.Aggregate(Join);
}
output.Add(suffix[0]);
} else {
rn = rand.Next(suffix.Count);
output.Add(suffix[rn]);
}
if (output.Count >= outputSize) {
return output.Take(outputSize).Aggregate(Join);
}
n++;
prefix = output.Skip(n).Take(keySize).Aggregate(Join);
}
}
// static void Main(string[] args) {
// Console.WriteLine(MarkovChain("leviathan.txt", 3, 300));
// }
}
}