using System; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; namespace FastRngTests; [ExcludeFromCodeCoverage] public sealed class IntFrequencyAnalysis { private readonly uint[] data; public IntFrequencyAnalysis(int maxValue = 100) { this.data = new uint[maxValue]; } public void CountThis(int value) { this.data[value]++; } public float[] GetNormalizedEvents() { var max = (float)this.data.Max(); var result = new float[this.data.Length]; for (var n = 0; n < this.data.Length; n++) { result[n] = this.data[n] / max; } return result; } private float[] Normalize() { var max = (float)this.data.Max(); var result = new float[this.data.Length]; for (var n = 0; n < this.data.Length; n++) result[n] = this.data[n] / max; return result; } public float[] NormalizeAndPlotEvents(Action writer) { var result = this.Normalize(); Plot(result, writer, "Event Distribution"); return result; } public void PlotOccurence(Action writer) { var data = this.data.Select(n => n > 0f ? 1.0f : 0.0f).ToArray(); Plot(data, writer, "Occurrence Distribution"); } private static void Plot(float[] data, Action writer, string name) { const int HEIGHT = 16; var values = new float[data.Length]; for (var n = 0; n < data.Length; n++) { values[n] = data[n] * HEIGHT; } var sb = new StringBuilder(); for (var line = HEIGHT; line > 0; line--) { for (var column = 0; column < data.Length; column++) sb.Append(values[column] >= line ? '█' : '░'); writer.Invoke(sb.ToString()); sb.Clear(); } writer.Invoke(name); writer.Invoke(string.Empty); } }