Решение этой задачи потребует большего количества программирования. Поэтому её имеет смысл давать интересным кандидатам, как домашнее задание. Если хотите посмотреть как человек реально пишет код. Кроме того, задача содержит внутри себя возможность для выбора решения из нескольких возможных. Посмотреть на то увидит ли кандидат разные возможности и чем будет руководствоваться при выборе, так же интересно.
Мне её давали на собеседовании в Exigen.
Задача
Реализовать интерфейс для банкомата. Устройство получает запросы через стандартный ввод и отправляет ответы в стандартный вывод. Все команды возвращают OK, в случае успеха, и ERROR, в случае ошибки.
Возможны следующие команды.
1. Внести купюры.
+ <валюта> <номинал купюры> <количество>
<валюта> — три любые заглавные буквы.
<номинал купюры> — допустимые значения: 10n и 5*10n, 0<=n<=3.
<количество> — любое положительное, целое число.
2. Выдать наличные.
— <валюта> <сумма>
<валюта> — валюта.
<сумма> — любое положительное, целое число.
3. Распечатать имеющиеся купюры.
?
На каждую пару валюта/купюра печатает строку следующего вида:
<валюта> <номинал купюры> <количество>
Строки сгруппированы по валютам и отсортированы по номиналам.
Решение
В задаче, на мой взгляд, имеются несколько моментов, на реализацию которых нужно обратить внимание.
Первый — классическая задача о том, как выдать какую-то сумму имеющимися купюрами. Эта задача должна быть известна любому приличному программисту.
Второй — если нам не удалось выдать запрашиваемую сумму, то количество купюр в банкомате не должно измениться.
Третий — самый интересный. Как хранить информацию о количестве имеющихся купюр так, чтобы к ней можно было быстро и удобно получать доступ.
С учётом жёстких ограничений на номиналы купюр, напрашивается хранить количество купюр в массиве длины 8 и вычислением индекса массива следующим образом:
int index = value.charAt (0) -'2'+value.length ();
Подозреваю, что именно этот ход и ожидали увидеть авторы. Решение милое, но очень сильно завязано на указанные в задании номиналы банкнот.
Более разумным мне кажется решение, которое, по моим прикидкам, не должно сильно отличаться по производительности, но дает значительную гибкость в определении номиналов. Кроме того, из ATM не требуется выжимать максимальную производительность.
Идея в том, что номиналы и количество хранятся в двух массивах, длины 8. Массив с номиналами отсортирован, для возможности бинарного поиска по нему. При необходимости найти индекс массива, где хранится информация о количестве купюр необходимого номинала, мы ищем соостветствующий номинал в первом массиве и используем этот индекс, для доступа ко второму.
При таком подходе нам совершенно всё равно, какие конкретно номиналы допустимы.
Предлагаемое решение можно посмотреть тут: Реализация задачи про банкомат (721)