Skip to content

Instantly share code, notes, and snippets.

@TheFo2sh
Last active November 21, 2020 18:11
Show Gist options
  • Save TheFo2sh/833879e37e8aeb0436df1d3928338fa8 to your computer and use it in GitHub Desktop.
Save TheFo2sh/833879e37e8aeb0436df1d3928338fa8 to your computer and use it in GitHub Desktop.
OrderProcessing.ts
import * as R from 'Ramda';
namespace Main {
export interface Order {
Amount: number
Name: string
}
export interface Discount {
Apply: (amount: number) => number;
IsValid: (order: Order) => boolean;
}
export module OrderProcessing {
const AmountLens=R.lensProp("Amount");
const WithAmount = (newAmount: number, order: Order) => R.over(AmountLens, (_) => newAmount, order);
const CanApplyDiscount = (discount: Discount, order: Order) => discount.IsValid(order);
const ApplyDiscount = (discount: Discount, order: Order) => R.pipe(() => discount.Apply(order.Amount), (newAmount) => WithAmount(newAmount, order))();
const ApplyDiscountIfValid = (discount: Discount, order: Order) => R.when((order: Order) => CanApplyDiscount(discount, order), (order: Order) => ApplyDiscount(discount, order), order);
const ApplyAllDiscounts = (order: Order, discounts: Discount[]) => R.map(discount => ApplyDiscountIfValid(discount, order), discounts);
const ApplyLimitedNumberOfDiscounts = (order: Order, discounts: Discount[], numberOfDiscounts: number) => R.pipe(() =>
ApplyAllDiscounts(order, discounts),
result => R.filter(discountedOrder => discountedOrder.Amount != order.Amount, result),
result=>R.sortBy(discount=>discount.Amount,result),
result => R.take(numberOfDiscounts, result))();
const Median = R.unapply<number>((inputs)=>R.pipe((numbers:number[])=>R.filter(val=>val!=0,numbers),R.median) (<number[]>inputs));
const ReduceDiscountedOrders = (order1: Order, order2: Order) =>R.pipe(()=>Median(order1.Amount, order2.Amount),(newAmount:number)=> WithAmount(newAmount, order1))();
export const ApplyValidDiscounts = (order: Order, discounts: Discount[], numberOfDiscounts: number) => R.reduce(ReduceDiscountedOrders, WithAmount(0,order), ApplyLimitedNumberOfDiscounts(order, discounts, numberOfDiscounts))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment