Created
September 23, 2011 15:14
-
-
Save dornatsky/1237614 to your computer and use it in GitHub Desktop.
taxes calculation
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; | |
using System.Text; | |
namespace ConsoleApplication1 | |
{ | |
class Program | |
{ | |
private static TaxRate[] _entries = new TaxRate[] | |
{ | |
new TaxRate(5070, 0.10m), | |
new TaxRate(8660, 0.14m), | |
new TaxRate(14070, 0.23m), | |
new TaxRate(21240, 0.30m), | |
new TaxRate(40230, 0.33m), | |
new TaxRate(null, 0.45m), | |
}; | |
public static void Main() | |
{ | |
var calculator = new TaxCalculator(_entries); | |
var taxes = new decimal[] { 5000, 5800, 9000, 15000, 50000 }.Select(sum => calculator.GetTaxes(sum)); | |
foreach (var sum in taxes) | |
{ | |
Console.WriteLine(sum); | |
} | |
} | |
} | |
public class TaxCalculator | |
{ | |
private TaxRate[] _policy; | |
public TaxCalculator(TaxRate[] policy) | |
{ | |
//TODO: Ensure that policy entries are ordered and the last one has open boundary value. | |
_policy = policy; | |
} | |
public decimal GetTaxes(decimal sum) | |
{ | |
if (sum < 0) | |
throw new ArgumentException("Incorrect sum"); | |
decimal result = 0; | |
decimal previousBound = 0; | |
foreach (var entry in _policy) | |
{ | |
bool stop; | |
decimal part = CalculatePart(sum, previousBound, entry, out stop); | |
result += part; | |
if (stop) break; | |
//Will not affect correctness, not relevant for the last step. | |
previousBound = entry.UpperBound ?? 0; | |
} | |
return result; | |
} | |
private decimal CalculatePart(decimal sum, decimal previousBound, TaxRate entry, out bool stop) | |
{ | |
stop = false; | |
decimal boundary = entry.UpperBound.HasValue ? entry.UpperBound.Value : decimal.MaxValue; | |
decimal result; | |
if (sum < boundary) | |
{ | |
result = (sum - previousBound) * entry.Rate; | |
stop = true; | |
} | |
else | |
{ | |
result = (boundary - previousBound) * entry.Rate; | |
} | |
return result; | |
} | |
} | |
public struct TaxRate | |
{ | |
public decimal? UpperBound; | |
public decimal Rate; | |
public TaxRate(decimal? boundary, decimal rate) | |
{ | |
UpperBound = boundary; | |
Rate = rate; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment