Harry Potter Discounts: A Code Challenge Algorithm
The enchanting world of Harry Potter has captured the hearts of readers young and old alike. Now, imagine a scenario where a bookshop endeavors to boost sales of the five different Harry Potter books by offering enticing discounts on multiple-book purchases. This captivating premise sets the stage for a fascinating code challenge: calculating the price of a shopping basket filled with Harry Potter books while maximizing discounts.
The Challenge Unveiled
The challenge is simple yet intriguing: calculate the total price of a shopping basket containing Harry Potter books, applying discounts based on the number of different titles purchased. Here's how the discounts unfold:
- One copy of any book: 8 EUR.
- Two different books: 5% discount.
- Three different books: 10% discount.
- Four different books: 20% discount.
- Five different books: 25% discount.
It's important to note that if a customer buys multiple books, but some are duplicates, the discount applies only to the unique titles.
Mission: Crafting the Code
Your mission, should you choose to accept it, is to write a piece of code capable of calculating the price of any conceivable shopping basket, ensuring that customers receive the maximum discount possible.
import { add } from "./index";
describe("index.js", () => {
it("one different book should return the price", () => {
const basket = [
{
title: "first",
price: 8,
},
];
const result = add(basket);
expect(result).toBe(8);
});
it("two different books should check for discount and return 5%", () => {
const basket = [
{
title: "first",
price: 8,
},
{
title: "second",
price: 8,
},
];
const result = add(basket);
expect(result).toBe((16 * 95) / 100);
});
it("three different books should check for discount and return 10%", () => {
const basket = [
{
title: "first",
price: 8,
},
{
title: "second",
price: 8,
},
{
title: "third",
price: 8,
},
];
const result = add(basket);
expect(result).toBe((24 * 90) / 100);
});
it("fourth different books should check for discount and return 20%", () => {
const basket = [
{
title: "first",
price: 8,
},
{
title: "second",
price: 8,
},
{
title: "third",
price: 8,
},
{
title: "fourth",
price: 8,
},
];
const result = add(basket);
expect(result).toBe((32 * 80) / 100);
});
it("fifth different books should check for discount and return 25%", () => {
const basket = [
{
title: "first",
price: 8,
},
{
title: "second",
price: 8,
},
{
title: "third",
price: 8,
},
{
title: "fourth",
price: 8,
},
{
title: "fifth",
price: 8,
},
];
const result = add(basket);
expect(result).toBe((40 * 75) / 100);
});
it("3 of different books and one similar, to get 10%", () => {
const basket = [
{
title: "first",
price: 8,
},
{
title: "second",
price: 8,
},
{
title: "third",
price: 8,
},
{
title: "first",
price: 8,
},
];
const result = add(basket);
expect(result).toBe(8 + (24 * 90) / 100);
});
});
Solution Overview
Let's delve into the solution provided in the accompanying code snippet. The solution is implemented in TypeScript and comprises an interface BasketItem representing individual items in the shopping basket. Additionally, there's a set of rules dictating the discount percentages based on the number of different books purchased. The add function takes an array of BasketItem objects as input and proceeds to calculate the total price, applying discounts according to the predefined rules. It intelligently handles scenarios where customers purchase multiple copies of the same book or a mix of different titles.
interface BasketItem {
title: string;
price: number;
}
interface DiscountRule {
bookNumbers: number;
discountPercentage: number;
}
const rules: DiscountRule[] = [
{ bookNumbers: 2, discountPercentage: 5 },
{ bookNumbers: 3, discountPercentage: 10 },
{ bookNumbers: 4, discountPercentage: 20 },
{ bookNumbers: 5, discountPercentage: 25 },
];
export function add(basketItems: BasketItem[]): number {
const uniqueItems: BasketItem[][] = [];
for (let i = 0; i < basketItems.length; i++) {
let isSet = false;
let j = 0;
while (!isSet) {
if (uniqueItems[j]) {
const found = uniqueItems[j].find(
(item) => item.title === basketItems[i].title
);
if (!found) {
uniqueItems[j].push(basketItems[i]);
isSet = true;
}
} else {
uniqueItems[j] = [basketItems[i]];
isSet = true;
}
j++;
}
}
let sum: number = 0;
for (let i = 0; i < uniqueItems.length; i++) {
const rule = rules.find(
(rule) => rule.bookNumbers === uniqueItems[i].length
);
if (rule) {
for (let j = 0; j < uniqueItems[i].length; j++) {
sum +=
((100 - rule.discountPercentage) / 100) * uniqueItems[i][j].price;
}
} else {
for (let j = 0; j < uniqueItems[i].length; j++) {
sum += uniqueItems[i][j].price;
}
}
}
return sum;
}
In conclusion, the Harry Potter discounts code challenge offers a delightful journey into the realm of programming logic and problem-solving. By crafting a solution capable of calculating prices while maximizing discounts, developers can demonstrate their coding prowess and attention to detail.
Whether you're a seasoned wizard in the world of coding or a budding apprentice eager to hone your skills, this challenge presents an exciting opportunity to immerse yourself in the magic of programming. So, grab your wand (or keyboard) and embark on this enchanting adventure into the world of Harry Potter discounts!