using System.Collections.Generic;
public record Order(string Customer,int Items, decimal Cost);
static public decimal CalculateDiscount(Order order) =>
{Items: > 10, Cost: > 1000.00m} => 0.10m,
{Items: > 5, Cost: > 500.00m} => 0.05m,
Order { Cost: > 250.00m } => 0.02m,
null => throw new ArgumentNullException(nameof(order), "Can't calculate discount on null order"),
public record Discount(int Items, decimal Cost, decimal DiscountPercentage);
static IEnumerable<Discount> Discounts = new Discount[]
new Discount(10, 1000.00m, 0.10m),
new Discount(5, 500.00m, 0.05m),
new Discount(0, 250.00m, 0.02m),
new Discount(0, 0.0m, 0.0m),
static public decimal CalulateDiscountFromLookup(Order order)
var discounts = Discounts.Where(d => order.Items > d.Items && order.Cost > d.Cost);
if (discounts.Count() > 0)
return discounts.Max(d => d.DiscountPercentage);
static IEnumerable<Order> InitTestData(Random r)
var customers = new String[] {"Cust1","Cust2","Cust3","Cust4"};
return Enumerable.Range(1,12).Aggregate(new List<Order>()
a.Add(new (customers[x % 4],r.Next(50)
, Convert.ToDecimal(3500*r.NextDouble())));
public record OrderTotal (String Customer, Double OrderCount,decimal Total, decimal Discount);
static IEnumerable<OrderTotal> CalcResults(IEnumerable<Order> orders)
return orders.GroupBy(o => o.Customer).Select(obc =>
decimal totalBeforeDiscount = obc.Sum(o => o.Cost);
decimal totalAfterDiscount = obc.Sum(o => o.Cost * (1 - CalculateDiscount(o)));
return new OrderTotal(obc.Key, obc.Count(), totalBeforeDiscount, totalAfterDiscount);
#region alternate interpretation of requirements.
public static void Main()
var data = InitTestData(new Random()).ToList();
foreach( var p in CalcResults(data))
Console.WriteLine("Customer {0} Order Count {1} Total {2} Discount {3:#.##}"
,p.Customer,p.OrderCount,p.Total,p.Discount);