Skip to content

Instantly share code, notes, and snippets.

@cocoabox
Last active December 26, 2019 19:15
Show Gist options
  • Select an option

  • Save cocoabox/17b8ca75d203b7d9e9f819f816a24cfd to your computer and use it in GitHub Desktop.

Select an option

Save cocoabox/17b8ca75d203b7d9e9f819f816a24cfd to your computer and use it in GitHub Desktop.
savings.js
/*
--input.txt--
13 5 5
900 600 700 600 2000 2300 1600 500 2800 1500 1900 2200 2500
--EOF--
*/
process.stdin.resume();
process.stdin.setEncoding('utf8');
const LOG=true;
var stdin = '';
process.stdin.on('data', function (chunk) {
stdin += chunk;
}).on('end', function() {
var lines = stdin.trim().split('\n');
let line0 = lines[0].split(' ').map(n => parseInt(n));
let product_count = line0[0];
let a_count = line0[1];
let b_count = line0[2];
let product_prices = lines[1].split(' ').map(n => parseInt(n)).sort((a, b) => {
return b - a;
});
let prices = product_prices.map(pp => {
let a = pp * 0.95;
let b = pp >= 1000 ? pp - 100 : pp;
let a_discount = pp - a;
let b_discount = pp - b;
return {price:pp, a, b, a_discount, b_discount,
coup : a_discount > b_discount ? 'a' : 'b',
used : '',
};
});
prices.sort((p, q) => q.price - p.price);
// output
let pay = 0;
// all B coupons
let b_used = 0;
LOG && console.log('== phase 1 : use up all B coupons ==');
prices.filter(p => p.used === '').filter(p => p.coup === 'b').forEach(p => {
if (! b_count) return;
b_count--;
LOG && console.log('using B on :' , JSON.stringify(p), ' ... saves $', p.b_discount );
pay += p.b;
p.used ='b';
b_used++;
});
LOG && console.log(`used ${b_used} B coupons ; got ${b_count} more B coupons`);
let a_used = 0;
function use_a_coupons() {
prices.filter(p => p.used === '').sort((p, q)=>q.a_discount - p.a_discount).forEach(p => {
if (! a_count) return;
a_count--;
LOG && console.log('using A on :' , JSON.stringify(p), ' ... saves $', p.a_discount );
pay += p.a;
p.used ='a';
a_used++;
});
}
LOG && console.log('== phase 2 : use up all A coupons ==');
use_a_coupons();
if (b_count) {
let prices_old = JSON.parse(JSON.stringify(prices));
let pay_old = pay;
LOG && console.log('== phase 3 : sacrifice some A==');
// reverse some A coupon usage; starting from the product with least savings
prices.filter(p => p.used === 'a' && p.b_discount).sort((p, q)=>p.a_discount - q.a_discount).forEach(p => {
if (! b_count) return;
LOG && console.log('using B instead of A on :' , JSON.stringify(p), ' ... saves $', p.b_discount, 'using B , instead of $', p.a_discount);
pay -= p.a;
p.used = 'b';
pay += p.b;
b_used++;
b_count--;
a_used--;
a_count++;
});
use_a_coupons();
// examine whether we have saved money
function pay_how_much(price_list) {
let out = 0;
price_list.forEach(p => {
out += p.used === 'a' ? p.a : p.used ==='b' ? p.b : p.price;
});
return out;
}
let pay_pre = pay_how_much(prices_old);
let pay_new = pay_how_much(prices);
if (pay_new < pay_pre) {
console.log(`after swapping coupons, we're paying ${pay_new} instead of ${pay_pre} (total of $ ${pay_pre - pay_new} extra savings!)`);
}
else {
console.log('we are better off not swapping coupons');
pay = pay_old;
prices = prices_old;
}
}
LOG && console.log('== phase 4 : full price ==');
prices.filter(p => p.used === '').forEach(p => {
LOG && console.log('paying full price :', JSON.stringify(p));
pay += p.price;
});
LOG && console.log('== conclusion ==');
LOG && console.log(`we have ${a_count} A coupons unused; ${b_count} B coupons unused`);
console.log(pay);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment