- Должна быть функция “заправки” денег в банкомат - отправляется количество купюр каждого номинала (например, 10 купюр по “50", 8 по “25” и т.д.). Номиналы бывают: 1, 2, 5, 10, 25, 50.
- Реализовать метод который принимает сумму для выдачи и возвращает нужные номиналы. Если в банкомате не хватает денег для выдачи - пользователь должен получить сообщение об этом.
- Например, если поступил запрос на выдачу 200, а в наличии есть 3 купюры по 50 и 4 по 25, то результат может быть таким: {50 => 3, 25 => 2} или {50 => 2, 25 => 4}.
- Количество денег в наличии должно уменьшаться после каждой выдачи.
*install redis server to store data*
bundle
rackup config.ru
bash ping.sh
Имеем шесть номиналов банкнот, которые в результате их количественных комбинаций должны давать некоторую сумму Y
k0*x0+k1*x1+k2*x2+k3*x3+k4*x4+k5*x5 = Y
- ki - номинал банкнот
- xi - количество этих номиналов
- Y - сумма
Для подбора нужно определить некоторые границы. Очевидно, что
ki*xi
в отдельности не может быть больше Y
. Это больше, чем необходимо.
Следовательно, xi
должно быть меньше Y/ki
либо равно количеству фактически
загруженных в банкомат денег.
Мы определили верхнюю границу. Но так же понятно, что есть и нижняя
граница. Что она из себя представляет?
Легче понять это так. Если ki*xi
настолько мал, при максимальном xi
, что
со всеми максимальными остальными ki*xi
не может набрать необходимую сумму Y
,
то смысла рассматривать комбинации, где xi
меньше этого значения нету.
Таким образом, мы можем построить для номиналов ki хэш с границами поиска вида
ki => [xi_min, xi_max]
Затем делаем перебор по этим границам и получаем все возможные варианты.
Алгоритм не применим к ситуациям, когда загружено много мелких купюр. Например, 200 купюор по 2 и 400 купюр по 1 увеличивают количество вариантов выдачи в 200*400 раз, то есть 80000 раз, что просто приведет к зависанию реального банкомата.
Для ускорения выдачи купюр после загрузки денег можно сразу пытаться
искать комбинацию простым способом деления Y
с большего ki
, разделяя
остаток.
Этот метод не сработает, если комбинация в принципе возможна, но купюр уже недостаточно в банкомате, чтобы реализовать конкретную комбинацию.