Problems › TypeScript › pricing
Which pack size is the best value
The same product sits on the shelf in several pack sizes. A price-comparison badge needs the one with the lowest cost per unit.
- Compare price per unit, not sticker price.
- Skip any pack claiming zero or fewer units — that is bad data, not a bargain.
- On a tie, the larger pack wins.
- With nothing worth comparing, return null.
cheapestPack(packs: list<Pack>) → string?
Where you start
function cheapestPack(packs: Pack[]): string | null {
}
Worked examples
| Call | Result |
|---|---|
cheapestPack([{"label":"single","units":1,"price":300},{"label":"six","units":6,"price":1500},{"label":"crate","units":24,"price":6200}]) | "six" |
cheapestPack([{"label":"a","units":2,"price":200},{"label":"b","units":4,"price":400}]) | "b" |
cheapestPack([{"label":"broken","units":0,"price":100},{"label":"ok","units":3,"price":900}]) | "ok" |
cheapestPack([]) | null |
Hint
Cross-multiply instead of dividing: a.price * b.units against b.price * a.units keeps it in integers.
Reference solution in TypeScript
function cheapestPack(packs: Pack[]): string | null {
let best: Pack | null = null;
for (const p of packs) {
if (p.units <= 0) continue;
if (best === null) {
best = p;
continue;
}
const a = p.price * best.units;
const b = best.price * p.units;
if (a < b || (a === b && p.units > best.units)) best = p;
}
return best === null ? null : best.label;
}