Reputation: 4164
I have an offer configured with discount values and applicable volume range.
Its possible multiple offers applicable for a product, so I am looking for algorithm to consolidate overlapping volume range among various offers and show final discount applicable. Below code snippet would help to visualize the ask :
class VolumeTierRange
{
public int Min { get; set; }
public int Max { get; set; }
public int Discount { get; set; }
}
/* Offer1Range */
List<VolumeTierRange> Offer1Ranges = new List<VolumeTierRange>{
new VolumeTierRange {Min=1, Max=20, Discount=2 },
new VolumeTierRange {Min=21, Max=49 , Discount=10 },
new VolumeTierRange {Min=50, Max=100 , Discount=5 },
new VolumeTierRange {Min=101, Max=1000, Discount=15}
};
/* Offer2Range */
List<VolumeTierRange> dicountBRanges = new List<VolumeTierRange>{
new VolumeTierRange {Min = 1, Max=50, Discount=6},
new VolumeTierRange {Min=51, Max=1000, Discount=10 }
};
Consolidated result would look like :
List<VolumeTierRange> effectiveDiscount = new List<VolumeTierRange>{
new VolumeTierRange {Min=1, Max=20, Discount=8 },
new VolumeTierRange {Min=21, Max=49, Discount=16},
new VolumeTierRange {Min=50, Max=50, Discount=11},
new VolumeTierRange {Min=51, Max=100, Discount=15},
new VolumeTierRange {Min=101,Max=1000,Discount=25}
};
I do have some ways to achieve the expected outcome, but those all does not seems to be very intuitive.
Additional Info: Min value of first item and Max value of all offers is fixed (like 1 and 1000 in this example). Also there cannot be discontinuity while defining volume range.
Upvotes: 0
Views: 145
Reputation: 82474
Well, the first thing you want to do is figure out what values in Offer1Ranges
overlap what values in dicountBRanges
.
Items overlap when the min value of the first item is less then (or equal*) to the max value of the second item, while the min value of the second item is less then (or equal*) to the max value of the first item. For more information, see the overlap tag info.
Once you've joined the lists based on the overlapping items, it's a simple enough select to get the biggest of the two min values, the smallest of the two max values, and the sum of the discount value for each item:
var query = from o in Offer1Ranges
from d in dicountBRanges
where o.Min <= d.Max
&& o.Max >= d.Min
select new VolumeTierRange()
{
Min = (o.Min > d.Min) ? o.Min : d.Min,
Max = (o.Max < d.Max) ? o.Max : d.Max,
Discount = o.Discount + d.Discount
};
You can see a live demo or rextester.
*In your case, you consider the items overlapping even if it's on a single point (min of first equals the max of second or vice versa). This is not the general case.
Please note: This solution will only work as long as both lists starts and ends in the same numbers, and there are no gaps, as stated in the question:
"Additional Info: Min value of first item and Max value of all offers is fixed (like 1 and 1000 in this example). Also there cannot be discontinuity while defining volume range."
Upvotes: 2