module app; import std.algorithm, std.string, std.random, std.stdio, std.range, std.file; import manakasi.mecab; class Markov{ private{ static immutable begin = "_BEGIN_", end = "_END_"; //連鎖時数 static immutable d = 3; string[][] dic; } void study(string seed){ string[] ss = segment(seed); ss = begin ~ ss ~ end; //d+1次の組の生成 for(int offset; offset < ss.length - (d - 2); offset++) dic ~= (d + 1).iota.map!(i => ss[offset+i]).array; } void showDic(){ foreach(e; dic) e.writeln; } string build(){ string[][] begins; string result; int sentLeng = getRand % 100 + 10; foreach(e; dic) if(e[0] == begin) if(!this.find(begins, e[1..$])) begins ~= e[1..$]; string[] current = randomGet(begins); result = current.join; while(){ string targets = current[1 .. $]; string[] sugs; foreach(e; dic) if(e[0..$ - 1] == targets) if(!this.find(sugs, e)) sugs ~= e[$ - 1]; string sug = randomGet(sugs); current = current[1..$ - 1] ~ sug; if(current[$ - 1] == end){ break; } result ~= sug; } return result; } private{ bool find(T)(T[] array, T elem){ foreach(e; array) if(e == elem) return true; return false; } T randomGet(T)(T[] base){ return base[cast(uint)(getRand % base.length)]; } auto getRand(){ Mt19937 gen; gen.seed(map!((a) => unpredictableSeed)(repeat(0))); return gen.front; } } } void main(){ Markov markov = new Markov; string data = cast(string)read("./merosu.txt"); foreach(s; data.split("\n")) markov.study(s); markov.build.writeln; }