Skip to content

Instantly share code, notes, and snippets.

@dotjosh
Created September 23, 2011 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dotjosh/1237210 to your computer and use it in GitHub Desktop.
Save dotjosh/1237210 to your computer and use it in GitHub Desktop.
Ayende blog tax solution
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace TaxAyende
{
internal class Program
{
static void Main(string[] args)
{
var taxableAmount = new TaxCalculator().CalculateTax(17000);
Console.WriteLine(taxableAmount);
Console.ReadLine();
}
}
public class TaxCalculator
{
private static TaxRate[] _taxRates = new[]
{
TaxRate.Create(10, 0, 5070),
TaxRate.Create(14, 5070, 8660),
TaxRate.Create(23, 8660, 14070),
TaxRate.Create(30, 14070, 21240),
TaxRate.Create(33, 21240, 40230),
TaxRate.Create(45, 40230, decimal.MaxValue)
};
public decimal CalculateTax(decimal amount)
{
return _taxRates.Sum(tr => tr.TaxableAmount(amount));
}
}
public class TaxRate
{
public decimal Percentage { get; set; }
public decimal Min { get; set; }
public decimal Max { get; set; }
public static TaxRate Create(decimal percentage, decimal min, decimal max)
{
return new TaxRate { Percentage = percentage, Min = min, Max = max };
}
private decimal LargestTaxableAmount
{
get { return Max - Min; }
}
public decimal TaxableAmount(decimal amount)
{
return amount >= Min
? Percentage * .01m * Math.Min(amount - Min, LargestTaxableAmount)
: 0;
}
}
[TestFixture]
public class Tests
{
[Test]
public void Tax10()
{
var calc = new TaxCalculator();
decimal tax = calc.CalculateTax(5000);
Assert.AreEqual(500, tax);
}
[Test]
public void Tax14()
{
var calc = new TaxCalculator();
decimal tax = calc.CalculateTax(5800);
Assert.AreEqual(609.2m, tax);
}
[Test]
public void Tax23()
{
var calc = new TaxCalculator();
decimal tax = calc.CalculateTax(9000);
Assert.AreEqual(1087.8m, tax);
}
[Test]
public void Tax30()
{
var calc = new TaxCalculator();
decimal tax = calc.CalculateTax(15000);
Assert.AreEqual(2532.9m, tax);
}
[Test]
public void Tax45()
{
var calc = new TaxCalculator();
decimal tax = calc.CalculateTax(50000);
Assert.AreEqual(15068.1m, tax);
}
}
}
@jethrob
Copy link

jethrob commented Sep 26, 2011

Hi dotjosh, if you run your code with 5,800 as shown in Ayende's post you don't get 609.2 as an answer. This is because you are calculating the Tax from 5071 and not from 5070. Now the question says from 5071 up to 8660 but if you do that then your answer will differ from the expected results. ?? I could be missing something though.

@dotjosh
Copy link
Author

dotjosh commented Sep 26, 2011

Thanks, I fixed the issue.. the problem you weren't seeing was the percentage conversion being one "zero" off.

@jethrob
Copy link

jethrob commented Sep 26, 2011

Cool, I see you've changed the 5071 to 5070, I wonder why in Ayende blog he said 5071 up to 8660 and not 5070 to 8660? Great stuff!

@dotjosh
Copy link
Author

dotjosh commented Sep 26, 2011

The ranges are correct, but subtracting by that amount means you won't tax the first dollar.

@jethrob
Copy link

jethrob commented Sep 26, 2011

Exactly, it should be 5070 up to 8660. well it should actually be x > 5070 & x <= 8660 makes more sence. I guess I'm just being painfull. :)

@dotjosh
Copy link
Author

dotjosh commented Sep 26, 2011

Well from a domain/business perspective, the original tax ranges were correct e.g. the 14% tax rate would not include 5070), So that would be the better way to define the tax rate table for our business users, that table would probably map directly to some configuration screen in the UI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment