Menu
Coddy logo textTech

Оповещения о низком уровне запасов

Часть раздела Логика и управление потоком путешествия по Kotlin на Coddy. Урок 60 из 63.

challenge icon

Задание

Сложно

Завершите runInventory с параметрами commands: List<String>. Создайте инвентарь, который начинается пустым при каждом вызове функции. Каждая команда представляет собой одну строку с полями, разделёнными символом |. Имена предметов — слова в нижнем регистре, состоящие из ASCII-символов. Всего может быть не более 100 команд. Разделяйте каждую команду по буквальному разделителю; команды всегда содержат правильное количество полей для своей операции. Возвращайте один ответ на каждую команду. Перед разбором количества удаляйте окружающие пробелы; допустимые значения находятся в диапазоне от 0 до 1000. Некорректный числовой текст, текст со значением за пределами диапазона Int, отрицательные значения или значения больше 1000 должны приводить к ответу invalid без изменения состояния. Сохраняйте всё, что было написано на предыдущих шагах, включая каждую предыдущую команду и ответ. Поддержите ADD|item|quantity: добавляйте допустимое количество к запасу этого предмета, изначально равному нулю, и возвращайте ответ added. Добавление нуля также создаёт предмет. Добавьте GET|item: возвращайте его количество в виде строки или 0, если предмет отсутствует. Добавьте SELL|item|quantity: сначала проверяйте количество по тем же правилам, что и для ADD. Для допустимого количества возвращайте insufficient, если доступный запас меньше этого количества; в противном случае вычитайте его и возвращайте sold. У отсутствующего предмета доступный запас равен нулю. Продажа нулевого количества выполняется успешно, не создавая отсутствующий предмет. Сохраняйте существующие предметы с нулевым запасом. Добавьте REPORT: возвращайте все сохранённые записи в формате item=quantity, разделённые символом ; и отсортированные по именам предметов в алфавитном порядке. Включайте записи с нулевым запасом. Для пустого инвентаря возвращайте empty. У REPORT нет полей аргументов. Добавьте LOW|threshold: проверяйте порог по тем же числовым правилам, что и количества. При некорректном вводе возвращайте invalid. В противном случае возвращайте имена сохранённых предметов, количество которых строго меньше порога, отсортированные в алфавитном порядке и разделённые символом ;, либо none, если подходящих предметов нет. LOW не изменяет запас. На этом шаге во входных данных используются только поддерживаемые операции.

Если выше не указаны более строгие ограничения, коллекции содержат не более 100 элементов на каждом уровне, а целочисленные аргументы и целочисленные значения коллекций находятся в диапазоне от -1000 до 1000. Текст, предоставленный для разбора, может содержать некорректные представления или представления со значениями за пределами диапазона, как описано выше.

Возвращайте значение типа List<String>. Сохраните предоставленный код ввода/вывода. Он считывает скалярные аргументы по одному в строке; список начинается с его размера, за которым следуют его элементы, а map начинается с количества записей, за которым следуют каждый ключ и значение. Для вложенных списков формат с количеством и элементами повторяется для каждой строки. Предоставленный main выводит возвращаемое значение, за которым следует один перевод строки. Списки используют стандартный формат Kotlin со скобками; не выводите дополнительные метки.

Попробуйте сами

fun runInventory(commands: List<String>): List<String> {
    val stock = mutableMapOf<String, Int>()
    val replies = mutableListOf<String>()
    for (command in commands) {
        val parts = command.split("|")
        val operation = parts[0]
        val item = if (parts.size > 1) parts[1] else ""
        when (operation) {
            "ADD" -> {
                val amount = parts[2].trim().toIntOrNull()
                if (amount == null || amount !in 0..1000) replies.add("invalid")
                else {
                    stock[item] = (stock[item] ?: 0) + amount
                    replies.add("added")
                }
            }
            "GET" -> replies.add((stock[item] ?: 0).toString())
            "SELL" -> {
                val amount = parts[2].trim().toIntOrNull()
                val available = stock[item] ?: 0
                if (amount == null || amount !in 0..1000) replies.add("invalid")
                else if (amount > available) replies.add("insufficient")
                else {
                    if (stock.containsKey(item)) stock[item] = available - amount
                    replies.add("sold")
                }
            }
            "REPORT" -> {
                if (stock.isEmpty()) replies.add("empty")
                else replies.add(stock.keys.sorted().map { "$it=${stock[it]}" }.joinToString(";"))
            }
        }
    }
    return replies
}
fun main() {
    val commandsCount = readln().toInt()
    val commands = mutableListOf<String>()
    for (i0 in 0 until commandsCount) {
        val commandsItem = readLine().orEmpty()
        commands.add(commandsItem)
    }
    println(runInventory(commands))
}

Все уроки раздела Логика и управление потоком

Потренируйтесь самостоятельно: Песочница Kotlin