Last active
September 3, 2015 21:44
-
-
Save simoneb/215545 to your computer and use it in GitHub Desktop.
KataPotter
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
[TestFixture] | |
public class Test : Calculator | |
{ | |
[Test] | |
public void No_books_are_0() | |
{ | |
Assert.AreEqual(0, Price()); | |
} | |
[Test] | |
public void One_book_is_8() | |
{ | |
Assert.AreEqual(8, Price(0)); | |
} | |
[Test] | |
public void Two_same_books_is_16() | |
{ | |
Assert.AreEqual(8 * 2, Price(0, 0)); | |
} | |
[Test] | |
public void Three_same_books_is_24() | |
{ | |
Assert.AreEqual(8 * 3, Price(1, 1, 1)); | |
} | |
[Test] | |
public void Two_distinct_books_should_get_5_percent_discount() | |
{ | |
Assert.AreEqual(8 * 2 * 0.95, Price(0, 1)); | |
} | |
[Test] | |
public void Three_distinct_books_should_get_10_percent_discount() | |
{ | |
Assert.AreEqual(8 * 3 * 0.9, Price(0, 2, 4)); | |
} | |
[Test] | |
public void Four_distinct_books_should_get_20_percent_discount() | |
{ | |
Assert.AreEqual(8 * 4 * 0.8, Price(0, 1, 2, 4)); | |
} | |
[Test] | |
public void Five_distinct_books_should_get_25_percent_discount() | |
{ | |
Assert.AreEqual(8 * 5 * 0.75, Price(0, 1, 2, 3, 4)); | |
} | |
[Test] | |
public void Mixed_case() | |
{ | |
Assert.AreEqual(8 + (8 * 2 * 0.95), Price(0, 0, 1)); | |
} | |
[Test] | |
public void Complex_case() | |
{ | |
Assert.AreEqual(51.2, Price(0, 0, 1, 1, 2, 2, 3, 4)); | |
} | |
[Test] | |
public void I_fell_on_this_one() | |
{ | |
Assert.AreEqual(78.8, Price(0, 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 4)); | |
} | |
[Test] | |
public void And_on_this_one_too() | |
{ | |
Assert.AreEqual(100, Price(0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4)); | |
} | |
} |
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
public class Calculator | |
{ | |
public decimal Price(params int[] books) | |
{ | |
var cart = new Cart(books); | |
return cart.Total; | |
} | |
} |
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
public class Cart | |
{ | |
private readonly Collection<BookSet> bookSets = new Collection<BookSet>(); | |
public Cart(params int[] books) | |
{ | |
var sortedByOccurrence = books.GroupBy(b => b) | |
.OrderByDescending(g => g.Count()) | |
.SelectMany(b => b); | |
foreach (var b in sortedByOccurrence) | |
Add(b); | |
} | |
private void Add(int book) | |
{ | |
if (bookSets.Any(s => s.CanAccept(book))) | |
bookSets.Where(g => g.CanAccept(book)) | |
.OrderBy(s => TotalWithNewBookInSet(s, book)) | |
.First() | |
.Accept(book); | |
else | |
bookSets.Add(new BookSet(book)); | |
} | |
public decimal Total | |
{ | |
get { return TotalWith(bookSets); } | |
} | |
private decimal TotalWithNewBookInSet(BookSet set, int book) | |
{ | |
return TotalWith(bookSets.Except(new[]{set})) + set.TotalWith(book); | |
} | |
private decimal TotalWith(IEnumerable<BookSet> sets) | |
{ | |
return sets.Sum(s => s.Total); | |
} | |
} |
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
internal class BookSet | |
{ | |
private readonly List<int> books = new List<int>(); | |
public BookSet(int book) | |
{ | |
books.Add(book); | |
} | |
public decimal Total | |
{ | |
get { return TotalWith(books); } | |
} | |
private static decimal ComputeDiscount(IEnumerable<int> books) | |
{ | |
switch(books.Count()) | |
{ | |
case 1: return 0m; | |
case 2: return 0.05m; | |
case 3: return 0.1m; | |
case 4: return 0.2m; | |
case 5: return 0.25m; | |
default: throw new NotSupportedException(); | |
} | |
} | |
public bool CanAccept(int book) | |
{ | |
return !books.Contains(book); | |
} | |
public void Accept(int book) | |
{ | |
books.Add(book); | |
} | |
public decimal TotalWith(int book) | |
{ | |
return TotalWith(books.Concat(new[] {book})); | |
} | |
private static decimal TotalWith(IEnumerable<int> books) | |
{ | |
return 8 * books.Count() * (1 - ComputeDiscount(books)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment