Как обработать ситуацию нехватки банкнот при выдаче суммы и вернуть ошибку
Что проверяют
Умеете ли вы довести алгоритм до корректного состояния: заметить, что жадный подход работает не всегда, и не испортить остаток банкнот при неудачной выдаче. Ошибка здесь проверяется как часть контракта функции. Следом обычно просят исправить код и написать тесты на граничные случаи.
Как отвечать
Разделите задачу на три части: расчёт, проверку и фиксацию.
- расчёт без побочных эффектов: функция принимает сумму и остаток, возвращает набор купюр или признак неудачи и ничего не меняет. Остаток уменьшают только после успешного расчёта, иначе неудачная попытка оставит автомат с «пропавшими» купюрами;
- жадный алгоритм не всегда верен: при ограниченном числе купюр он ошибается. Есть одна купюра 100, одна 50 и четыре по 20, нужно 130. Жадный возьмёт 100 и 20 и застрянет на остатке 10, хотя 50 + 20 × 4 даёт ровно 130. Корректно решает перебор с возвратом или динамическое программирование по сумме с учётом лимитов;
- формат ошибки: либо
throwсвоего класса (class InsufficientBanknotesError extends Error) с полемcode, либо возврат объекта вида{ ok: false, reason: 'NOT_ENOUGH_BANKNOTES' }. Второй вариант удобнее в UI: причина типизирована, и не нужно ловить исключения; - разные причины: сумма не кратна минимальному номиналу, в автомате вообще не хватает денег, купюры есть, но нужной комбинации нет. Пользователю полезно знать, какая именно, и получить подсказку, например ближайшую доступную сумму;
- валидация входа: ноль, отрицательные и дробные значения, строка из инпута.
На фронтенде результат переводится в состояние формы: сообщение об ошибке рядом с полем, кнопка остаётся активной, введённая сумма не сбрасывается.
Где спотыкаются
Уменьшают остаток прямо в цикле расчёта. Когда комбинация не нашлась, купюры уже списаны, а при фиксации могут списаться второй раз.
Забывают, что Object.keys возвращает строки. sort() без компаратора сравнит их лексикографически, и '100' окажется меньше '20', а += со строкой склеит значения вместо сложения.
Проверяют только суммы, которые жадный алгоритм решает. Тест на 130 из примера выше ломает большинство первых решений.