Guest User

Ayende's Tax Rate Problem

a guest
Sep 23rd, 2011
351
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.60 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using NUnit.Framework;
  5.  
  6. namespace Spikes.AyendesTaxProblem
  7. {
  8.     [TestFixture]
  9.     // http://ayende.com/blog/108545/the-tax-calculation-challenge
  10.     public class TaxCalculatorTests
  11.     {
  12.         private TaxCalculator calculator;
  13.  
  14.         [SetUp]
  15.         public void SetUp()
  16.         {
  17.             var rates = new[]
  18.             {
  19.                 new TaxRate(     0,             5070, 10 ),
  20.                 new TaxRate(  5071,             8660, 14 ),
  21.                 new TaxRate(  8661,            14070, 23 ),
  22.                 new TaxRate( 14071,            21240, 30 ),
  23.                 new TaxRate( 21241,            40230, 33 ),
  24.                 new TaxRate( 40231, decimal.MaxValue, 45 ),
  25.             };
  26.             calculator = new TaxCalculator(rates);
  27.         }
  28.  
  29.         [TestCase(  5000.0,   500.0 )]
  30.         [TestCase(  5800.0,   609.2 )]
  31.         [TestCase(  9000.0,  1087.8 )]
  32.         [TestCase( 15000.0,  2532.9 )]
  33.         [TestCase( 50000.0, 15068.1 )]
  34.         public void CalculateTax_SpecifiedEarnings_EqualsResult(decimal earnings, decimal expected)
  35.         {
  36.             var actual = calculator.CalculateTax(earnings);
  37.             Assert.That(actual, Is.EqualTo(expected));
  38.         }
  39.     }
  40.  
  41.     public class TaxRate
  42.     {
  43.         public decimal LowerBound  { get; private set; }
  44.         public decimal UpperBound  { get; private set; }
  45.         public decimal RatePercent { get; private set; }
  46.  
  47.         public TaxRate(decimal lowerBound, decimal upperBound, decimal rate)
  48.         {
  49.             LowerBound  = lowerBound;
  50.             UpperBound  = upperBound;
  51.             RatePercent = rate;
  52.         }
  53.     }
  54.  
  55.     public class TaxCalculator
  56.     {
  57.         private readonly IEnumerable<TaxRate> rates;
  58.  
  59.         public TaxCalculator(IEnumerable<TaxRate> rates)
  60.         {
  61.             if (rates == null) throw new ArgumentNullException("rates");
  62.             this.rates = rates;
  63.         }
  64.  
  65.         public decimal CalculateTax(decimal earnings)
  66.         {
  67.             return rates
  68.                 .Where(rate => rate.LowerBound <= earnings)
  69.                 .Select(rate => rate.RatePercent * getTaxableAmount(rate, earnings) / 100m)
  70.                 .Sum();
  71.         }
  72.  
  73.         private decimal getTaxableAmount(TaxRate rate, decimal gross)
  74.         {
  75.             // dirty hack for unspecified inter-rate gap.
  76.             var min = Math.Max(0m, rate.LowerBound - 1);
  77.  
  78.             var max = Math.Min(gross, rate.UpperBound);
  79.  
  80.             var taxableAmt = max - min;
  81.  
  82.             return taxableAmt;
  83.         }
  84.     }
  85. }
Advertisement
Add Comment
Please, Sign In to add comment