Problem: Calculate Prices for Experiment Groups

hard
40 min
Extend your pricing system to dynamically select and apply different pricing algorithms based on each user’s experiment group at runtime.

Problem statement

You’re rolling out a real-time A/B pricing experiment for your e-commerce platform. Users are automatically assigned to different experiment groups to test new pricing strategies:

  • Group A (Conservative): Small 5% markup to maintain conversion rates.

  • Group B (Aggressive): 25% markup to test premium positioning.

  • Group C (Dynamic): Algorithmic pricing that fluctuates based on simulated demand.

A central experiment service determines the user’s assigned group, for example:

getExperimentGroup(userId) → 'A' | 'B' | 'C'

Pricing experiments often rely on nested conditionals to handle different pricing models, which quickly become unmanageable as experiments evolve. A typical implementation is as follows:

const group = getExperimentGroup(userId);
if (group === 'A') { /* conservative logic */ }
else if (group === 'B') { /* aggressive logic */ }
else if (group === 'C') { /* dynamic logic */ }

It works—but every experiment update means changing core code. You’ll now design a pricing system using the Strategy Pattern, so each pricing model is encapsulated and selected dynamically at runtime.

Goal

Implement both sides of the pattern:

  1. Strategies (Pricing algorithms):

    1. ConservativePricing: Adds 5% markup.

    2. AggressivePricing: Adds 25% markup.

    3. DynamicPricing: Randomly adds 0–50% markup.

    4. Each defines .calculate(basePrice) and returns a two-decimal formatted number.

  2. Context (PricingService):

    1. Delegates .calculate() to the injected strategy.

    2. Adds a .setStrategy() method for runtime swapping.

  3. Experiment logic:

    1. Implement getExperimentGroup(userId) that assigns groups randomly.

    2. Use it to dynamically select and inject the correct pricing strategy.

Constraints

  • No if or switch inside PricingService.

  • Strategy selection should happen externally (via a simple mapping or factory).

  • Prices must be returned as numbers with 2 decimal places.

  • DynamicPricing should produce different results on multiple runs.

Sample output

The examples below illustrate what the output should look like:

const userId = Math.floor(Math.random() * 1000);
const basePrice = 100;
const group = getExperimentGroup(userId);
const strategy = selectStrategyForGroup(group);
const service = new PricingService(strategy);
console.log(`User ${userId} assigned to Group ${group}`);
console.log('Final price:', service.calculate(basePrice));
/* Expected output (varies due to randomization):
User 517 assigned to Group C
Final price: 138.42
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Problem: Calculate Prices for Experiment Groups

hard
40 min
Extend your pricing system to dynamically select and apply different pricing algorithms based on each user’s experiment group at runtime.

Problem statement

You’re rolling out a real-time A/B pricing experiment for your e-commerce platform. Users are automatically assigned to different experiment groups to test new pricing strategies:

  • Group A (Conservative): Small 5% markup to maintain conversion rates.

  • Group B (Aggressive): 25% markup to test premium positioning.

  • Group C (Dynamic): Algorithmic pricing that fluctuates based on simulated demand.

A central experiment service determines the user’s assigned group, for example:

getExperimentGroup(userId) → 'A' | 'B' | 'C'

Pricing experiments often rely on nested conditionals to handle different pricing models, which quickly become unmanageable as experiments evolve. A typical implementation is as follows:

const group = getExperimentGroup(userId);
if (group === 'A') { /* conservative logic */ }
else if (group === 'B') { /* aggressive logic */ }
else if (group === 'C') { /* dynamic logic */ }

It works—but every experiment update means changing core code. You’ll now design a pricing system using the Strategy Pattern, so each pricing model is encapsulated and selected dynamically at runtime.

Goal

Implement both sides of the pattern:

  1. Strategies (Pricing algorithms):

    1. ConservativePricing: Adds 5% markup.

    2. AggressivePricing: Adds 25% markup.

    3. DynamicPricing: Randomly adds 0–50% markup.

    4. Each defines .calculate(basePrice) and returns a two-decimal formatted number.

  2. Context (PricingService):

    1. Delegates .calculate() to the injected strategy.

    2. Adds a .setStrategy() method for runtime swapping.

  3. Experiment logic:

    1. Implement getExperimentGroup(userId) that assigns groups randomly.

    2. Use it to dynamically select and inject the correct pricing strategy.

Constraints

  • No if or switch inside PricingService.

  • Strategy selection should happen externally (via a simple mapping or factory).

  • Prices must be returned as numbers with 2 decimal places.

  • DynamicPricing should produce different results on multiple runs.

Sample output

The examples below illustrate what the output should look like:

const userId = Math.floor(Math.random() * 1000);
const basePrice = 100;
const group = getExperimentGroup(userId);
const strategy = selectStrategyForGroup(group);
const service = new PricingService(strategy);
console.log(`User ${userId} assigned to Group ${group}`);
console.log('Final price:', service.calculate(basePrice));
/* Expected output (varies due to randomization):
User 517 assigned to Group C
Final price: 138.42
*/

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Node.js
// --- Strategies (implement these) ---
class ConservativePricing {}
class AggressivePricing {}
class DynamicPricing {}
// --- Context (implement this too) ---
class PricingService {
constructor(strategy) {}
setStrategy(strategy) {}
calculate(basePrice) {}
}
// --- Experiment setup ---
function getExperimentGroup(userId) {
// Simulate random assignment to A, B, or C
const groups = ['A', 'B', 'C'];
const index = userId % 3;
return groups[index];
}
function selectStrategyForGroup(group) {
// TODO: Return the appropriate pricing strategy
}
// Example usage
const userId = Math.floor(Math.random() * 1000);
const basePrice = 100;
const group = getExperimentGroup(userId);
const strategy = selectStrategyForGroup(group);
const service = new PricingService(strategy);
console.log(`User ${userId} assigned to Group ${group}`);
console.log('Final price:', service.calculate(basePrice));
/* Expected output (varies due to randomization):
User 517 assigned to Group C
Final price: 138.42
*/