Skip to content

Instantly share code, notes, and snippets.

@UniBreakfast
Created May 19, 2023 19:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save UniBreakfast/bd14529f0e8753a3f74d392463bc3f8b to your computer and use it in GitHub Desktop.
Save UniBreakfast/bd14529f0e8753a3f74d392463bc3f8b to your computer and use it in GitHub Desktop.
Minimum required coins to reach the given input amount
/*
Task: Minimum required coins to reach the given input amount
Given a list of coins: 500, 200, 100, 50, 20, 10, 2, 1, 0.5, 0.2, 0.1, 0.02, 0.01
Given input amount: 3763.58
Expected output:
{
500:7,
200:1,
100:0,
50:1,
20:0,
10:1,
2:1,
1:1,
0.5:1,
0.2:0,
0.1:0,
0.02:4,
0.01:0
}
*/
const cache = {};
// console.log(giveCoins([10, 4, 3, 0.01], 5));
console.log(giveCoins([500, 200, 100, 50, 20, 10, 2, 1, 0.5, 0.2, 0.1, 0.02, 0.01], 3763.58));
function giveCoins(coins, amount) {
if (coins.some(coin => coin < 1)) {
const result = giveCoins(coins.map(coin => coin * 100), amount * 100)
return Object.fromEntries(Object.entries(result).map(([coin, count]) => [coin / 100, count]))
}
const key = coins.toString()
const results = cache[key] || {}
cache[key] = results
return iter(amount)
function iter(amount) {
if (results[amount]) return results[amount]
if (amount === 0) return {}
const i = coins.findIndex(coin => coin <= amount)
if (i === -1) throw new Error('impossible')
const slice = coins.slice(i)
for (const coin of slice) {
try {
const result = add({[coin]: 1}, iter(amount - coin))
results[amount] = result
return result
} catch {}
}
throw new Error('impossible')
}
}
function add(obj1, obj2) {
const result = {...obj1}
for (const key in obj2) result[key] = (result[key] || 0) + obj2[key]
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment