using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
class MainClass {
static void Main() {
var limit = 100000;
var chances = 10;
var possibleOutcomes = "HT";
var patterns = new List<string> { "HTT", "HTH" };
var patternFormat = $"{{0,-{patterns.Select(x => x.Length).Max()}}}";
Console.WriteLine($"Settings: \n{limit,10} Iterations (for precision)\n{string.Join(", ", possibleOutcomes.ToCharArray()),10} are the possible outcomes");
Console.WriteLine("Checking for bad data...");
for(var i = 0; i < patterns.Count; i++)
{
var pattern = patterns[i];
if(!pattern.Any())
{
patterns.RemoveAt(i--);
Console.WriteLine(" Removed empty pattern");
}
else if(pattern.Except(possibleOutcomes).Any())
{
patterns.RemoveAt(i--);
Console.WriteLine($" {pattern} contains illegal characters");
}
}
Console.WriteLine("Calculating...");
var found = new bool[patterns.Count];
var counts = new int[patterns.Count][];
for(var i = 0; i < patterns.Count; i++)
{
counts[i] = new int[limit];
}
Func<int,string> statsStats = (i) =>
{
var sum = 0.0;
var length = patterns[i].Length;
var list = new List<int>();
for(int j = length; j < 1000; j++)
list.Add(counts[i].Count(j.Equals));
return string.Concat(
"(",
string.Join(", ", list.Take(chances).Select(x => $"{Math.Round(1000.0*x/limit)/10.0,5:0.0}%")),
" ) ",
list.TakeWhile(x => (sum += (1.0*x/limit)) <= 0.90).Count()
);
};
var stats = (Func<int,string>)((i) => $"{string.Format(patternFormat,patterns[i])} avg {Math.Round(counts[i].Average()),-2} {statsStats(i)}");
var rand = new Random();
for(int i = 0; i < limit; i++)
{
for(var j = 0; j < patterns.Count; j++)
found[j] = false;
var serie = new StringBuilder();
while(found.Any(false.Equals))
{
serie.Append(possibleOutcomes[rand.Next(possibleOutcomes.Length)]);
for(var pattern = 0; pattern < patterns.Count; pattern++)
if(serie.Length >= patterns[pattern].Length
&& !found[pattern])
if(Regex.Match(serie.ToString(), $"{patterns[pattern]}$").Success)
{
found[pattern] = true;
counts[pattern][i] = serie.ToString().Length;
}
}
}
for(int i = 0; i < patterns.Count; i++)
Console.WriteLine(stats(i));
}
}