I am trying to design some code that will calculate a repayment plan for a loan, given a principle amount, term period (12 months) and and interest rate. I want the payments each month to be the same value (the last can differ slightly to account for remainders), and the interest is calculated from the remaining loan balance.
The basic rules are
Interest is dependant on the loan balance.
Loan balance is dependant on the total monthly repayment value.
Capital repayment is dependant on total monthly repayment value and interest.
The total monthly repayment amount can vary but must be the same each month (except the last one which can be different).
Here is the code I currently have, it does continous iterations until it finds the correct total monthly repayment value. This does work sort of but seems very inefficient and it takes the balance horribly into negative when it shouldnt . I'm wondering if anyone knows of a better way of doing this?
static void calcRepaymentPlan()
{
decimal loanAmount = 100000; //100,000
decimal ir = 0.10m;
//day counts
int[] days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
//get month/days
int dayCount = days.Sum();
int months = days.Length;
//get interest values
decimal interestdaily = ir / dayCount;
//total each month
decimal ideal_total_repayment = (loanAmount / months); //random number but seems like the best place to start
//some arrays to store balances
decimal[] balances = null;
decimal[] interest = null;
decimal[] capitalrepayment = null;
decimal totalRepaymentsValue = 0;
while (totalRepaymentsValue != loanAmount)
{
//array for balance each month
balances = new decimal[months];
for (int i = 0; i < months; i++)
{
balances[i] = loanAmount - ((i+1) * ideal_total_repayment);
}
//array for interest each month
interest = new decimal[months];
for (int i = 0; i < months; i++)
{
interest[i] = (interestdaily * balances[i]) * days[i];
}
//array for capital each month
capitalrepayment = new decimal[months];
for (int i = 0; i < months; i++)
{
capitalrepayment[i] = ideal_total_repayment - interest[i];
}
//how much of the loan are we paying back?
totalRepaymentsValue = capitalrepayment.Sum();
//how much difference between the loan amount and the total we have got now?
decimal difference = loanAmount - totalRepaymentsValue;
//how much to increment
decimal incr = 1;
//are we within 100? if so make the increment finer
if (difference < 100)
incr = 0.1m;
//if the difference is less than 1, then just add/subtract it from the last repayment
if (difference < 1)
{
capitalrepayment[months - 1] += difference;
balances[months - 1] += difference;
//this should now be the
totalRepaymentsValue = capitalrepayment.Sum();
continue;
}
//change the ideal total repayment
ideal_total_repayment += totalRepaymentsValue < loanAmount ? incr : -incr;
}
Console.WriteLine("--------------------------------------------------------------------------------------");
Console.WriteLine(" Balance Capital Interest Total Repayment");
for (int i = 0; i < months; i++)
{
string balanceStr = balances[i].ToString("#,##0.00");
string capitalStr = capitalrepayment[i].ToString("#,##0.00");
string interestStr = interest[i].ToString("#,##0.00");
string totalStr = (capitalrepayment[i] + interest[i]).ToString("#,##0.00");
Console.WriteLine("{0}). {1} {2} {3} {4}", (i + 1),
balanceStr, capitalStr, interestStr, totalStr);
}
Console.WriteLine("Ideal Total Repayment Value : {0}", ideal_total_repayment);
Console.WriteLine("Total Repaying : {0}", totalRepaymentsValue);
Console.WriteLine("-------------------------------------------------------------------------------------");
}
Related
I have an assignment where I need to calculate the amount of money for 2 people where we have 2 different interest rates. I need to display the amount of money that they would have at each of the given age. The issue is that it only prints the final amount which is 60 years old, how do I print the correct amount at the correct age? Here is the code
Console.WriteLine("*************************Investing vs.Savings ************************* \n");
Console.WriteLine("{0,-25} {1,-30} {2,-30}","Age", "Linda's Account", "John's Account");
Console.Write("-----------------------------------------------------------------------\n");
for(int age=20;age<=60;age+=10)
{
double Linda = 1000;
double John = 1000;
for (int year=1;year<=40;year++)
{
double retLin = 0.06;
double retJon = 0.015;
Linda += Linda * retLin;
John += John * retJon;
}
Console.WriteLine("{0,-25}{1,-30:0.00} {2,-35:0.00}", age, Linda, John);
}
Console.Read();
If I figured it right, your desired response is a line of output for each person's balance on each deacde. To do this you only need one iteration in wich balances are increased based on each person's interest rate.
But to calculate the interest rate correctly, it should be added to the balance on every year. So a fixed inner loop of 10 iterations is needed for each decade.
The code is:
double Linda = 1000;
double John = 1000;
double retLin = 0.06;
double retJon = 0.015;
for (int age = 30; age <= 60; age += 10)
{
for (int i = 0; i < 10; i++)
{
Linda += Linda * retLin;
John += John * retJon;
}
Console.WriteLine("{0,-25}{1,-30:0.00} {2,-35:0.00}", age, Linda, John);
}
Note that this will not print tha balance on the starting decade (you can simply print the starting values before the loop operations).
I think this is what you need (comments in code):
Console.WriteLine("*************************Investing vs.Savings ************************* \n");
Console.WriteLine("{0,-25} {1,-30} {2,-30}", "Age", "Linda's Account", "John's Account");
Console.Write("-----------------------------------------------------------------------\n");
// It always is good idea to store info in variables, to give
// them meaning and easily parametrize the code.
var baseAge = 20;
var ageStep = 10;
var finalAge = 60;
// Of course, it would not make sense if you'd have just simple loop
// i = 0, i < limit, i++.
for (int age = baseAge; age <= finalAge; age += ageStep)
{
double Linda = 1000;
double John = 1000;
// Here you missed starting point, as it always calculated
// as if we were in first loop - we need account for that.
for (int year = age; year <= 40; year++)
{
double retLin = 0.06;
double retJon = 0.015;
Linda += Linda * retLin;
John += John * retJon;
}
Console.WriteLine("{0,-25}{1,-30:0.00} {2,-35:0.00}", age, Linda, John);
}
Console.Read();
Ok so im completely lost i have never done any kind of c# coding and am trying to learn.
The task I have to do:
Calculate the parking fee for each customer, and put that out together with the hours parked.
There is a maximum parking fee of $20.00.
Calculate and output the average of the parking fees.
Overall Tasks:
Read the data file ‘hours.txt’ into an array of data type integer
Calculate the parking fee for each customer and output the hours parked and the parking fee.
Calculate the average parking fee
Output the average parking fee (formatted to 2 decimal places)
for now, declare your array and assign the numbers as shown below.
This is what i have come up with so far.
And plaese remember that like i said im very NEW to this and I´m looking for some guidence.
int[] hours;
hours = new int[30];
const decimal HOURLY_RATE = 2.50m;
const decimal MAX_FEE = 20.00m; //Capped at S20.00
decimal parkFee;
decimal parkingCost = HOURLY_RATE;
int[] hoursArray = { 8, 24, 9, 7, 6, 12, 10, 11, 23, 1, 2, 9, 8, 8, 9, 7, 9, 15, 6, 1, 7, 6, 12, 10, 11, 23, 1, 2, 9, 8 };
Console.WriteLine("Hours " + "Parking Fee ");
int total = 0;
double average = 0;
for (int index = 0; index < hours.Length; index++)
if (parkingCost > MAX_FEE)
{
parkFee = parkingCost * MAX_FEE;
Console.WriteLine("Hours " + "Parking Fee ");
}
average = (double)total / hours.Length;
Console.WriteLine("Average = " + average.ToString("N2"));
Console.ReadKey();`
You never calculate your fee before you check if it's bigger than the maximum rate. Therefore you don't see any results, since your fee is never calculated (always 0). Also, you miss some braces for the for loop, so it will not loop through your code under the for loop.
A quick fix:
int[] hours = new int[30]{ 8, 24, 9, 7, 6, 12, 10, 11, 23, 1, 2, 9, 8, 8, 9, 7, 9, 15, 6, 1, 7, 6, 12, 10, 11, 23, 1, 2, 9, 8 };
const decimal HOURLY_RATE = 2.50m;
const decimal MAX_FEE = 20.00m; //Capped at S20.00
Console.WriteLine("Hours and fee's parked per person");
decimal total = 0;
for (int index = 0; index < hours.Length; index++)
{
decimal parkFee = HOURLY_RATE * hours[index];
if (parkFee > MAX_FEE)
parkFee = MAX_FEE;
total += parkFee;
Console.WriteLine("Hours: {0}. Parking Fee: {1}", hours[index], parkFee);
}
decimal average = total / hours.Length;
Console.WriteLine("Average = {0}", average.ToString("N2"));
Console.ReadKey();
I also cleaned up some variables that are double and moved some variable declarations to the place where they are calculated. I also made a decimal value out of your total variable. You were using int which will only give you whole numbers which will lead to an inaccurate total amount of fee's. By using decimal you solve this problem. Lastly, I also changed you average value to a decimal, which seems to make more sense in this case since you use decimal for all variables so far.
EDIT: since you specifically ask for reading the array from a text file. This is how you create your hours array from your text file instead of declaring it in code:
const decimal HOURLY_RATE = 2.50m;
const decimal MAX_FEE = 20.00m; //Capped at S20.00
// See http://stackoverflow.com/a/556142/7397065 why you should use # here
string path = #"C:\your\path\here.txt";
string stringFromFile = File.ReadAllText(path);
// Since your array is delimited on whitespace, use null as parameter
// You also need int's instead of string. So directly convert the results to int.
// We now make a List(), which also gives you more flexibility.
// Want to change your delimiter? See https://msdn.microsoft.com/en-us/library/b873y76a(v=vs.110).aspx
List<int> hours = stringFromFile.Split(null).Select(int.Parse).ToList();
Console.WriteLine("Hours and fee's parked per person");
decimal total = 0;
// Let's change this to a foreach. That's clearer to work with.
foreach (int parkingTime in hours)
{
decimal parkFee = HOURLY_RATE * parkingTime;
if (parkFee > MAX_FEE)
parkFee = MAX_FEE;
total += parkFee;
Console.WriteLine("Hours: {0}. Parking Fee: {1}", parkingTime, parkFee);
}
// We have to use .Count now, since we use List()
decimal average = total / hours.Count;
Console.WriteLine("Average = {0}", average.ToString("N2"));
Console.ReadKey();
Easiest solution would be to just iterate through hoursArray and check for the lowest value between each park period times rate and maximum fee. Then just add this to your total fees and after all divide this by your array's length :
for ( int i = 0; i < hoursArray.Length; ++i )
{
// get the lowest value
parkFee = Math.Min(hoursArray[i] * HOURLY_RATE, MAX_FEE);
// add to total fees
total += parkFee;
// print current iteration state
Console.WriteLine("Hours : {0}, Parking fee : {1}", hoursArray[i], parkFee);
}
// calculate the average
average = total / (double)hoursArray.Length;
// print results
Console.WriteLine("Average : {0}", average.ToString("N2"));
I have different schemas for different kind of commission over the sales. From 0 to 10.000€ its pay a commission of 2%, from 10.001 to 20.000 the commission is 2.5%, 20.001 to 30.000 is payee a commission of 3% and so until the commission is 5% or more. The threshold amount and the commission is taken from the database in a list. The problem is that I have to take on account the sales since the beginning of the year to achieve the given threshold but only calculated the commission for the sale of the current month. For instance if the sales in a given month is 30.000 and the cumulated sales from the beginning of the year is 8.000, the calculation is: 2.000 at 2%, 10.000 at 2.5 %, 10.000 at 3% and 8.000 at 3.5% with a result of 870. This is the code that I have but don’t work fine. Any help would be appreciated. Thanks in advance.
foreach (var bound in fxCollection)
{
if (antAmount < bound.FinalAmount)
{
if (antAmount >= bound.InitialAmount && antAmount <= bound.FinalAmount)
{
if (totalAmount > bound.FinalAmount)
{
totalAmountCardSchema = totalPeriod - (bound.FinalAmount.Value - antAmount);
totalCommission += (bound.FinalAmount.Value - antAmount) * (bound.Commission / 100);
}
else
{
totalCommission += totalPeriod * (bound.Commission / 100);
totalCommission = 0;
}
}
else
{
if ((bound.FinalAmount - bound.InitialAmount) < totalAmountCardSchema)
{
if (index == count) //last loop
{
totalCommission += totalAmountCardSchema * (bound.Commission / 100);
totalAmountCardSchema = 0;
}
else
{
totalCommission += (bound.FinalAmount.Value - bound.InitialAmount.Value) * (bound.Commission / 100);
totalAmountCardSchema = totalAmountCardSchema - (bound.FinalAmount.Value - bound.InitialAmount.Value);
}
}
else if (totalAmountCardSchema > 0)
{
totalCommission += totalAmountCardSchema * (bound.Commission / 100);
totalAmountCardSchema = 0;
}
}
}
index++;
var valueInvoiceLine = totalCommission;
To clarify:
Yes, this is the point. In the example is fine. To clarify, the sales from 1th of January until 31th May was 8.000 and the sales in one month was 30.000. I put this example because I want loop in several band for calculate the commission of the month but for achieve the first band to calculate the initial band in this month I have to add the sales since the first day of the year. In the example the first band is from 0 to 10.000 but I have to add the sales for the first day of the year (8.000) and then of the sales of the month (30.000), I have to take only 2.000 in the first band, in the second band I have to take 10.000, in the third band I have to take another 10.000 and in the fourth band I have to take the rest (8.000). Sorry if it’s not very clear. I hope that you understand. Thanks you so much.
Try something like this
decimal totalAmount = 35;
decimal commission = 0.0M;
decimal commissionAmount = 0.0M;
Dictionary<decimal,decimal> commissions = new Dictionary<decimal,decimal>() {
{ 0, .02M}, ///2%
{ 10, .005M}, //2.5%
{ 20, .005M}, //3.0%
{ 30, .005M}, //3.5%
{ 40, .005M}, //4.0%
{ 50, .005M}, //4.5%
{ 60, .005M}, //5.0%
};
foreach (decimal key in commissions.Keys)
{
if (totalAmount > key)
{
commissionAmount = totalAmount - key;
}
else
{
commissionAmount = totalAmount - key < 0 ? 0 : totalAmount - key;
}
commission += commissionAmount * commissions[key];
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Every dates in the array represent a User interaction.
If there is a gap of > of 20 seconds between these dates I count a new User (lets call this group of dates a session).
Following my script I can count Users correctly.
But I cannot calculate the average time for session.
Could you point me out what am I doing wrong, of any suggestion for a better code is very welcome. Thanks.
namespace test_code
{
class Program
{
static void Main(string[] args)
{
Console.Clear();
DateTime[] dates = {
new DateTime(2014,01,01,0,0,0),
new DateTime(2014,01,01,0,0,5),
new DateTime(2014,01,01,0,0,10), // 15 s USR 1 session
new DateTime(2014,01,01,0,5,0),
new DateTime(2014,01,01,0,5,5), // 05 s USR 2
new DateTime(2014,01,01,0,10,0),
new DateTime(2014,01,01,0,10,1),
new DateTime(2014,01,01,0,10,2), // 03 s USR 3
new DateTime(2014,01,01,1,0,0),
new DateTime(2014,01,01,2,0,0),
new DateTime(2014,01,01,2,0,20) // 20 s USR 4
};
int users = dates.Length > 0 ? 1 : 0;
int gapS = 20; // Gap between date in seconds
double totalTimeGaps = 0;
double totalTime = 0;
for (int i = 0, n = i + 1; i < dates.Length - 1; i++, n++)
{
totalTime += (dates[n] - dates[i]).TotalSeconds;
if ((dates[n] - dates[i]).TotalSeconds > gapS)
{
users++;
totalTimeGaps += (dates[n] - dates[i]).TotalSeconds; // Does not count properly
Console.WriteLine(totalTimeGaps);
}
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Total Users: " + users);
Console.WriteLine("Total Time Avg. Session : " + (totalTime - totalTimeGaps)/users);
Console.ReadKey();
Console.Clear();
}
}
}
EDIT: Last version of working script
using System;
public class Program
{
public static void Main(string[] args)
{
DateTime[] dates = {
new DateTime(2014,01,01,0,0,0),
new DateTime(2014,01,01,0,0,5),
new DateTime(2014,01,01,0,0,10), // 10 s USR 1
new DateTime(2014,01,01,0,5,0),
new DateTime(2014,01,01,0,5,5), // 05 s USR 2
new DateTime(2014,01,01,0,10,0),
new DateTime(2014,01,01,0,10,1),
new DateTime(2014,01,01,0,10,2), // 02 s USR 3
new DateTime(2014,01,01,1,0,0), // 00 s USR 4
new DateTime(2014,01,01,2,0,0),
new DateTime(2014,01,01,2,0,20) // 20 s USR 5
};
int users = dates.Length > 0 ? 1 : 0;
int gapS = 20; // Gap between date in seconds
double totalTimeGaps = 0;
double totalTime = 0;
for (int i = 0, n = i + 1; i < dates.Length - 1; i++, n++)
{
double range = (dates[n] - dates[i]).TotalSeconds;
totalTime += range;
if (range > gapS)
{
users++;
totalTimeGaps += range;
}
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Total Users: " + users);
Console.WriteLine("Total Time Avg. Session : " + (totalTime - totalTimeGaps)/users);
Console.WriteLine("Total Time App." + (totalTime - totalTimeGaps));
}
}
The results I get are exactly as I'd expect when I run your program:
Total Users: 5
Total Time Avg. Session : 7.4
There are five users whose duration is 10s, 5s, 2s, 0s, 20s.
The total time is thus 37 seconds over 5 users which averages to 7.4s/user.
Your problem seems to be not in the code but in your own understanding of the data. You seem to have failed to note that what you record as user 4 is in fact two users and you are miscounting some of the timings (seemingly when there are three times involved).
Your code is correct according to the specs you gave us, you are just validating your code incorrectly.
Here is another approach using one List<DateTime> for every session-group:
List<List<DateTime>> sessions = new List<List<DateTime>> { new List<DateTime>() };
foreach(DateTime dt in dates)
{
if(!sessions.Last().Any())
sessions.Last().Add(dt);
else
{
TimeSpan diff = dt - sessions.Last().Last();
if (diff.TotalSeconds > 20)
sessions.Add(new List<DateTime> { dt });
else
sessions.Last().Add(dt);
}
}
You can use List<double> for every average:
List<double> secondsPerSession = new List<double>();
foreach (var session in sessions)
{
if (session.Count == 1)
secondsPerSession.Add(0);
else
{
double average = session.Skip(1)
.Average(d => (d - session[0]).TotalSeconds);
secondsPerSession.Add(average);
}
}
Output:
for (int i = 0; i < sessions.Count; i++)
Console.WriteLine("{0} [{1}]",
string.Join(",", sessions[i]), secondsPerSession[i]);
The problem is with your condition in you cycle. You count only the total gaps between two users and not the total time what a user has spent in your system. It should look something like this:
for (int i = 0, n = i + 1; i < dates.Length - 1; i++, n++)
{
totalTime += (dates[n] - dates[i]).TotalSeconds;
if ((dates[n] - dates[i]).TotalSeconds > gapS)
{
users++;
Console.WriteLine(totalTimeGaps);
}
else
{
totalTimeGaps += (dates[n] - dates[i]).TotalSeconds; // Does not count properly
}
}
Also if you want to get the average at the end of the cycle you should divide the total amount of time with the total number of users counter.
I want to calculate the amount to charge my customers, when they buy licenses of my product.
I sell it in ranges of licenses:
1-10 : $50/user
11-20 : $40/user
21-30 : $30/user
31-50 : $20/user
So when someone purchases 136 licenses, I will charge him:
50 x 2 x $20 = $2000
30 x 1 x $30 = $900
6 x $50 = $300
I'm looking for an algorithm on how to process the given number and break it into number of occurrences in a range..
How can I do this in plain C# or LINQ?
------------ EDIT ----------------------------
I started a less confusing question (Algorithm for Fogbugz pricing scheme) and I got the answer I've been looking for.
Thank you all..
If presented with this price structure I would think that it is in the customer's best interest to minimize the cost by buying the package that best suits their need. The following algorithm uses dynamic programming to calculate the minimal possible price to exactly buy a certain number of licenses (you can save money by buying more than you need, although I haven't implemented that):
int getPrice(int n)
{
if (n >= 1 && n <= 10) return 50 * n;
if (n >= 11 && n <= 20) return 40 * n;
if (n >= 21 && n <= 30) return 30 * n;
if (n >= 31 && n <= 50) return 20 * n;
throw new Exception("Impossible");
}
int minimizePrice(int n)
{
int[] minimumPrice = new int[n + 1];
for (int i = 1; i <= n; ++i)
{
minimumPrice[i] = int.MaxValue;
for (int j = Math.Max(0, i - 50); j < i; ++j)
{
minimumPrice[i] = Math.Min(minimumPrice[i],
minimumPrice[j] + getPrice(i - j));
}
}
return minimumPrice[n];
}
For 70 licenses the minimal price is $1400 which can be obtained by buying 2 blocks of 35 licenses. You are suggesting a greedy algorithm. This will confuse your customers. A clever customer will place two orders instead of one large order and save $400.
I'd suggest changing your prices so that there is no upper limit to the number of licenses you can buy at $20 each.
This looks like it would be very similar to algorithms that make change for purchases (which coins to choose). The only difference is that you're comparing against a range instead of a single number.
The code could look something like this:
var val = 136;
var price = 0;
while (val > 0)
{
var range = FindMatchingRange(val); // Use a dictionary, list, or array.
var number = Math.Min(val, range.Max);
price += range.CostPerUser * number;
val -= number;
}
If I were a person who needed 10 licenses, under your suggested pricing plan why would I ever buy just 10 licenses?
10 licenses * $50/license = $500
11 licenses * $40/license = $440
What you would want is plan that lowers the cost for the most recently purchased licenses. So that for person wanting 11 licenses they would pay:
(10 licenses * $50/license) + (1 license * $40/license) = $540
A possible plan would look like this:
first 10 licenses (1-10): $50/user
next 10 licenses (11-20): $40/user
next 10 licenses (21-30): $30/user
all licenses after that (31+) : $20/user
Writing code to compute final cost for any number of users is a simple exercise. The calculation for someone purchasing 136 licenses would look like this:
(10 licenses * $50/license) + (10 licenses * $40/license) + (10 licenses * $30/license) + (106 licenses * $20/license) = $500 + $400 + $300 + $2120 = $3,220.
The original pricing plan is wacky, in my opinion. Take the customer who purchased 130 licenses last year who comes back and wants 10 more. What justification is there for charging them the highest rate? They are a high volume customer, you want to sell them (and they justifiably expect to receive) additional licenses at the lowest "marginal" price.
I made a calculation class for you... just more customer-orientated.
It calculates the cheapest price possible with your defined priceranges.
Example: 136 Licenses
50 Licenses 20$ each ( because: 31-50 : $20/user )
50 Licenses 20$ each ( because: 31-50 : $20/user )
36 Licenses 20$ each ( because: 31-50 : $20/user )
TOTAL: 1720
Example 130 Licenses
50 Licenses 20$ each
50 Licenses 20$ each
30 Licenses 30$ each
TOTAL: 1900
Code for the class:
public class PriceCalculator
{
public List<OrderPackage> CalculateCheapestPrice(Int32 AmountOfLicenses,
List<PriceRange> PriceRanges, out Double Total)
{
List<OrderPackage> result = new List<OrderPackage>();
Total = 0;
Int32 AmountsOfLicensesleft = AmountOfLicenses;
PriceRanges.Sort(ComparePrice);
for (int i = 0; i < PriceRanges.Count; i++)
{
for (int j = PriceRanges[i].MaxAmount; j >= PriceRanges[i].MinAmount; j--)
{
if (j <= AmountsOfLicensesleft)
{
OrderPackage Order = new OrderPackage();
Int32 AmountOfThisPackage = AmountsOfLicensesleft / j;
//Int32 AmountForThisPrice = Convert.ToInt32(Math.Floor(tmp));
Order.PriceRange = PriceRanges[i];
Order.AmountOfLicenses = j;
Total += Order.AmountOfLicenses * Order.PriceRange.PricePerLicense;
for (int k = 0; k < AmountOfThisPackage; k++)
{
result.Add(Order);
}
AmountsOfLicensesleft = AmountsOfLicensesleft - (AmountOfThisPackage * j);
}
}
}
return result;
}
private static int ComparePrice(PriceRange x, PriceRange y)
{
if (x.PricePerLicense == y.PricePerLicense)
return 0;
if (x.PricePerLicense > y.PricePerLicense)
return 1;
if (x.PricePerLicense < y.PricePerLicense)
return -1;
return 0;
}
public class OrderPackage
{
public PriceRange PriceRange { get; set; }
public Int32 AmountOfLicenses { get; set; }
}
public class PriceRange
{
public int MinAmount { get; set; }
public int MaxAmount { get; set; }
public Double PricePerLicense { get; set; }
}
}
Usage example:
private void button1_Click(object sender, EventArgs e)
{
// Preparing PriceRangeDefinitions
List<PriceCalculator.PriceRange> PriceRangeDefinitions = new List<PriceCalculator.PriceRange>();
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 1, MaxAmount = 10, PricePerLicense = 50 });
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 11, MaxAmount = 20, PricePerLicense = 40 });
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 21, MaxAmount = 30, PricePerLicense = 30 });
PriceRangeDefinitions.Add(new PriceCalculator.PriceRange() { MinAmount = 31, MaxAmount = 50, PricePerLicense = 20 });
// Start the Calculation
PriceCalculator calculator = new PriceCalculator();
Double Total;
List<PriceCalculator.OrderPackage> Packages =
calculator.CalculateCheapestPrice(130, PriceRangeDefinitions, out Total);
// Show Proof of Concept
String ProofOfConcept = String.Empty;
for (int i = 0; i < Packages.Count; i++)
{
ProofOfConcept += Packages[i].AmountOfLicenses.ToString() + " Licenses " +
Packages[i].PriceRange.PricePerLicense.ToString() + "$ each" + Environment.NewLine;
}
ProofOfConcept += Environment.NewLine + "TOTAL: " + Total.ToString();
MessageBox.Show(ProofOfConcept);
}
A KeyValuePair collection or dictionary maybe?