Last active
May 1, 2020 17:48
-
-
Save justinAurand/67b05279af289e1bc7a84dc0a56d2c4a to your computer and use it in GitHub Desktop.
Order items randomly by weight
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
public class Program | |
{ | |
public void Main() | |
{ | |
var items = new List<WeightedItem> { | |
new WeightedItem { Name = "Chicken", Weight = 1 }, | |
new WeightedItem { Name = "Pizza", Weight = 3 }, | |
new WeightedItem { Name = "Turnip", Weight = 0 }, | |
}; | |
var itemsOrderedRandomlyByWeight = OrderRandomlyByWeight(items); | |
foreach (var item in itemsOrderedRandomlyByWeight) { | |
Console.WriteLine(item.Name); | |
} | |
} | |
private IOrderedEnumerable<WeightedItem> OrderRandomlyByWeight(List<WeightedItem> weightedItems) | |
{ | |
var random = new Random(); | |
var remainingItems = weightedItems.ToList(); | |
var orderedItems = new List<WeightedItem>(); | |
while (remainingItems.Count > 0) | |
{ | |
var totalWeight = remainingItems.Sum(item => item.Weight + 1); | |
var randomWeightIndex = random.Next(totalWeight); | |
var remainingItemWeightIndex = 0; | |
foreach (var remainingItem in remainingItems) | |
{ | |
remainingItemWeightIndex += remainingItem.Weight + 1; | |
if (remainingItemWeightIndex <= randomWeightIndex) | |
{ | |
continue; | |
} | |
orderedItems.Add(remainingItem); | |
remainingItems.Remove(remainingItem); | |
break; | |
} | |
} | |
// This is a no-op for casting purposes. | |
return orderedItems.OrderBy(item => 1); | |
} | |
private class WeightedItem { | |
public string Name { get; set; } | |
public int Weight { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment