1 module dcaptcha.markov;
2 
3 import std.algorithm;
4 import std.array;
5 import std.exception;
6 
7 import ae.utils.array;
8 
9 import dcaptcha.alice30;
10 
11 template MarkovChain(int LENGTH)
12 {
13 	immutable static string[][string[]] dictionary;
14 
15 	shared static this()
16 	{
17 		auto paragraphs =
18 			sourceText
19 			.split("\n\n")
20 			.map!(paragraph => paragraph
21 				.replace("\n", " ")
22 				.split()
23 				.assumeUnique()
24 			)
25 			.array();
26 
27 		string[][string[]] dic;
28 		foreach (paragraph; paragraphs)
29 		{
30 			foreach (int n; 0..cast(int)paragraph.length)
31 				dic[paragraph[max(n-LENGTH, 0)..n]] ~= paragraph[n];
32 			dic[paragraph[max(cast(int)$-LENGTH, 0)..$]] ~= null;
33 		}
34 		dictionary = dic.assumeUnique();
35 	}
36 
37 	string[] query()
38 	{
39 		string[] tail, result;
40 		immutable(string[])* p;
41 		while ((p = tail in dictionary) !is null)
42 		{
43 			auto next = (*p).sample;
44 			if (next is null)
45 				break;
46 			result ~= next;
47 			tail = result[max(cast(int)$-LENGTH, 0)..$];
48 		}
49 		return result;
50 	}
51 }
52 
53 version(markov_main)
54 void main()
55 {
56 	import std.stdio;
57 	writeln(MarkovChain!2.query().join(" "));
58 }