Skip to content

Instantly share code, notes, and snippets.

@anushshukla
Created March 7, 2021 21:13
Show Gist options
  • Select an option

  • Save anushshukla/53c2cb2bcf2b33fcc628bd8639f7f2ba to your computer and use it in GitHub Desktop.

Select an option

Save anushshukla/53c2cb2bcf2b33fcc628bd8639f7f2ba to your computer and use it in GitHub Desktop.
package main
import (
"testing"
)
const bookCost int = 8
type purchasedBooksStruct struct {
potterBooksList map[string]int
uniqueSets []int
totalPotterBooks int
bill float32
}
func (booksPurchased *purchasedBooksStruct) addPurchases(purchases map[string]int) {
booksPurchased.potterBooksList = purchases
}
func (booksPurchased *purchasedBooksStruct) setTotalBooksCount() {
sum := 0
for _, booksCount := range booksPurchased.potterBooksList {
sum += booksCount
}
booksPurchased.totalPotterBooks = sum
}
func (booksPurchased *purchasedBooksStruct) setUniqueSets() {
uniqueSets := make([]int, 0)
uniqueSetsCount := 0
potterBooksList := booksPurchased.potterBooksList
totalBooks := booksPurchased.totalPotterBooks
for totalBooks > 0 {
uniqueBooks := 0
for index, potterBook := range potterBooksList {
if potterBook > 0 {
uniqueBooks++
potterBooksList[index] = potterBook - 1
}
}
totalBooks = totalBooks - uniqueBooks
uniqueSetsLength := len(uniqueSets)
// for converting 5 and 3 sets of unique books copies to 4 and 4 as that has more concession
if uniqueSetsLength > 0 && uniqueBooks == 3 {
uniqueSets[uniqueSetsLength-1] = 4
uniqueBooks = 4
}
uniqueSets = append(uniqueSets, uniqueBooks)
uniqueSetsCount++
}
booksPurchased.uniqueSets = uniqueSets
}
func (booksPurchased *purchasedBooksStruct) setBill() {
var sum float32 = 0
for _, uniqueSet := range booksPurchased.uniqueSets {
sum += setDiscount[uniqueSet]
}
booksPurchased.bill = sum
}
var discounts = map[int]float32{
1: 0,
2: 0.05,
3: 0.10,
4: 0.20,
5: 0.25,
}
func getDiscountFor(uniqueBooksCount int) float32 {
total := float32(uniqueBooksCount * 8)
discount := total * discounts[uniqueBooksCount]
finalTotal := total - discount
return finalTotal
}
var setDiscount = map[int]float32{
1: getDiscountFor(1), // 8
2: getDiscountFor(2), // 15.2
3: getDiscountFor(3), // 21.6
4: getDiscountFor(4), // 25.6
5: getDiscountFor(5), // 30
}
func (booksPurchased *purchasedBooksStruct) getBill() float32 {
booksPurchased.setTotalBooksCount()
booksPurchased.setUniqueSets()
booksPurchased.setBill()
return booksPurchased.bill
}
// TestCalculateBill tests whether bill calculation amount is correct
func TestCalculateBill(t *testing.T) {
tests := []struct {
purchasedBooks map[string]int
expected float32
}{
{
purchasedBooks: map[string]int{
"firstBook": 2,
"secondBook": 2,
"thirdBook": 2,
"fourthBook": 1,
"fifthBook": 1,
},
expected: 51.2,
},
{
purchasedBooks: map[string]int{
"firstBook": 2,
"secondBook": 2,
"thirdBook": 3,
"fourthBook": 1,
"fifthBook": 1,
},
expected: 59.2,
},
{
purchasedBooks: map[string]int{
"firstBook": 4,
"secondBook": 4,
"thirdBook": 4,
"fourthBook": 3,
"fifthBook": 3,
},
expected: 111.2,
},
{
purchasedBooks: map[string]int{
"firstBook": 2,
"secondBook": 3,
"thirdBook": 3,
"fourthBook": 1,
"fifthBook": 1,
},
expected: 66.4,
},
{
purchasedBooks: map[string]int{
"firstBook": 2,
"secondBook": 1,
},
expected: 23.2,
},
}
for _, test := range tests {
purchasedBooks := purchasedBooksStruct{}
purchasedBooks.addPurchases(test.purchasedBooks)
t.Log("==============================")
t.Logf("Books purchased -> %v", test.purchasedBooks)
amount := purchasedBooks.getBill()
t.Logf("Total Books purchased -> %d", purchasedBooks.totalPotterBooks)
t.Logf("Unique Sets -> %v", purchasedBooks.uniqueSets)
t.Logf("Expected amount = %.2f", test.expected)
t.Logf("Calculated Amount = %.2f", amount)
if amount != test.expected {
t.Error("FAILED")
} else {
t.Log("PASSED")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment