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 }