using System.Collections.Generic;
public static void Main()
const int numberOfItems = 100;
const int classifications = 5;
var prices = new Dictionary<int, int>(){
var data = Enumerable.Range(1, numberOfItems).Select(x => (int)r.Next(1, classifications + 1));
var recommendationSet = GenerateRecommendationSetFromDataWithNormalDistribution(data, classifications);
foreach (var g in recommendationSet.Groups.OrderBy(g => g.Section))
var netAdjustment = g.Normalized - g.Original;
net += (prices[g.Section] * netAdjustment);
var netAdjustmentFormatted = (netAdjustment > 0) ? $"+{netAdjustment}" : $"{netAdjustment}";
Console.WriteLine($"CODE {g.Section}: {g.Original} -> {g.Normalized} ({netAdjustmentFormatted})");
Console.WriteLine($"NET WITH ADJUSTMENTS: {net:C}");
public int Code { get; set; }
public static (IEnumerable<double>, double, double) GenerateComparisonSetForSize(int size)
var list = new List<double>();
var min = double.MaxValue;
var max = double.MinValue;
for (var i = 0; i < size; i++)
var n = r.NextGaussian();
if (n > max) { max = n; }
if (n < min) { min = n; }
public static RecommendationSet GenerateRecommendationSetFromDataWithNormalDistribution(IEnumerable<int> data, int buckets)
(IEnumerable<double> nd, double min, double max) = GenerateComparisonSetForSize(data.Count());
var recommendationSet = new RecommendationSet(){
var list = new List<RecommendationGroup>();
var comparisonInterval = (max - min) / buckets;
for(var i = 1; i <= buckets; i++)
var cMin = (min + ((i - 1) * comparisonInterval));
var cMax = cMin + comparisonInterval;
list.Add(new RecommendationGroup(){
Original = data.Count(x => x == i),
Normalized = nd.Count(x => x >= cMin && x <= cMax)
recommendationSet.Groups = list;
return recommendationSet;
public class RecommendationSet
public IEnumerable<RecommendationGroup> Groups { get; set;}
public int Total { get; set; }
public class RecommendationGroup
public int Section { get; set; }
public int Original { get; set; }
public int Normalized { get; set; }
public static class RandomExtensions
public static double NextGaussian(this Random r, double mu = 0, double sigma = 1)
var rand_std_normal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
var rand_normal = mu + sigma * rand_std_normal;