using System.Collections.Generic;
using System.Collections;
public static void Main()
var properties = new List<string>()
var marbles = new List<Marble>();
var random = new Random();
for (var i=0; i < Math.Pow(2, properties.Count()); i++)
var marbleProps = new List<string>();
foreach (var prop in properties)
if (random.Next(properties.Count() * 2) == 1)
marbleProps.Add("not " + prop);
marbles.Add(new Marble() { Properties = marbleProps });
Console.WriteLine("Total marbles: " + marbles.Count());
foreach (var prop in properties)
Console.WriteLine($"Working set has {marbles.Count(x => x.Properties.Contains(prop))} marbles with [{prop}] as a characteristic");
foreach (var prop in properties.Select(p => "not " + p))
Console.WriteLine($"Working set has {marbles.Count(x => x.Properties.Contains(prop))} marbles with [{prop}] as a characteristic");
var selectedMarbles = new List<Marble>();
var selectionMultiplier = 10;
var selections = marbles.Count() * selectionMultiplier;
for (var i=0; i < selections; i++)
var index = random.Next(0, marbles.Count());
selectedMarbles.Add(marbles[index]);
Console.WriteLine($"Made {selections} selections");
foreach (var prop in properties)
var selected = selectedMarbles.Where(m => m.Properties.Contains(prop)).Count();
var expected = 1.0F * selections * marbles.Count(x => x.Properties.Contains(prop)) / marbles.Count();
Console.Write($"Selected {selected} marbles with {prop} - expected {expected}");
if (selected < (1.0F * expected * 0.95F))
Console.WriteLine($" -> This was underrepresented by {100 - 1.0F * selected / expected * 100}%");
else if (selected > (1.0F * expected * 1.05F))
Console.WriteLine($" -> This was overrepresented by {(100 - 1.0F * selected / expected * 100) * -1}%");
public List<string> Properties = new List<string>();