Как привести объект с номиналами купюр в правильный порядок для выдачи денег
Что проверяют
Знаете ли вы, как JavaScript упорядочивает ключи объекта. Вопрос с подвохом: номиналы вроде 100 и 50 это целочисленные ключи, и объект всегда перечисляет их по возрастанию, как бы вы их ни вставляли. Следом обычно просят написать саму выдачу суммы.
Как отвечать
Сначала покажите проблему:
const sorted = Object.fromEntries(
Object.entries({ 100: 5, 50: 10, 5000: 2 }).sort((a, b) => b[0] - a[0])
);
console.log(Object.keys(sorted)); // ['50', '100', '5000']Сортировка отработала, но при сборке обратно в объект порядок снова возрастающий. Правило из спецификации: сначала ключи, похожие на индексы массива, по возрастанию, затем строковые ключи в порядке вставки, затем символы. Значит, объект для упорядоченных данных не подходит, нужна другая структура:
- массив пар:
Object.entries(notes).map(([k, v]) => [Number(k), v]).sort((a, b) => b[0] - a[0]). Порядок гарантирован, по массиву удобно идти циклом; Map: сохраняет порядок вставки для любых ключей, включая числа. Отсортируйте пары, создайтеnew Map(pairs), и перебор пойдёт от крупных к мелким;- строковые ключи с префиксом вроде
n100объект оставит в порядке вставки, но это костыль, который путает читателя и ломает арифметику.
Дальше сама выдача: идём от крупного номинала, берём Math.min(count, Math.floor(rest / nominal)) купюр, уменьшаем остаток и помним, что купюры в кассете конечны. Если остаток не обнулился, сумму выдать нельзя, и списание откатывается.
Где спотыкаются
Сортируют массив, собирают объект через Object.fromEntries и считают задачу решённой. В консоли порядок снова возрастающий.
Сравнивают ключи как строки: sort() без компаратора ставит '100' перед '50'. Ключи из Object.entries всегда строки, их приводят через Number.
Не знают, что жадный алгоритм с ограниченным числом купюр ошибается. Сумму 60 при одной купюре 50 и трёх по 20 он не выдаст, хотя три по 20 подходят. Честный ответ: жадность работает для стандартного ряда номиналов без лимитов, в общем случае нужен перебор с возвратом или динамическое программирование.