Sobes.tech
Senior
45

# ბანკომატი, რომელიც იტვირთება კასეტებით ბილეთებით, ჩვენი აპლიკაციით ბორტზე # უნდა შეძლოს ბილეთების გამოტანა მითითებული თანხისთვის ან უარის მიცემა # ბილეთების გამოტანის დროს, ისინი ამოღებულია ბანკომატის ბალანსიდან. # დაშვებული ნომინალები: 50R, 100R, 500R, 1000R, 5000R. class ATM: pass # კოდის ადგილი # ბანკომატის მოწყობილობა: # - ფული განთავსებულია კასეტებში ბანკომატში, რომლებიც იტვირთება ინკასანტის მიერ და განახლდება; # - თითოეულ კასეტაში მდებარეობს თავისი ნომინალის ბილეთები; # - ბანკომატი შეუძლია ითვალოს დარჩენილი ბილეთები კასეტებში, მაგრამ ეს ოპერაცია გრძელია - უნდა იძახოს რაც შეიძლება იშვიათად. # API ბანკომატის აპარატურისთან ურთიერთქმედებისთვის: # SDK ინტერფეისი შეიძლება შეიცვალოს/გაფართოვდეს მხარეების შეთანხმებით, თუ ეს აუცილებელია class SDK(ABC): @abstractmethod def count_banknotes(self, banknote: int) -> int: pass @abstractmethod def move_banknote_to_dispenser(self, banknote: int, count: int) -> None: pass @abstractmethod def open_dispenser(self) -> None: pass

კომპანიებმა სადაც სთხოვეს
Яндекс

პასუხი AI-სგან

sobes.tech AI

python from abc import ABC, abstractmethod

class ATM: def init(self, sdk: SDK): self.sdk = sdk self.banknotes_cache = {}

def _update_cache(self):
    # Обновляем кэш количества банкнот для каждого номинала
    for banknote in [50, 100, 500, 1000, 5000]:
        self.banknotes_cache[banknote] = self.sdk.count_banknotes(banknote)

def _can_dispense(self, amount: int) -> bool:
    # Проверяем, можно ли выдать сумму с текущим кэшем
    # Используем жадный алгоритм по убыванию номиналов
    remaining = amount
    temp_cache = self.banknotes_cache.copy()
    for banknote in sorted(temp_cache.keys(), reverse=True):
        needed = remaining // banknote
        available = temp_cache[banknote]
        used = min(needed, available)
        remaining -= used * banknote
        temp_cache[banknote] -= used
        if remaining == 0:
            return True
    return False

def dispense(self, amount: int) -> bool:
    # Обновляем кэш перед выдачей
    self._update_cache()
    if amount <= 0 or amount % 50 != 0:
        return False  # Неверная сумма
    if not self._can_dispense(amount):
        return False  # Невозможно выдать сумму

    remaining = amount
    for banknote in sorted(self.banknotes_cache.keys(), reverse=True):
        needed = remaining // banknote
        available = self.banknotes_cache[banknote]
        used = min(needed, available)
        if used > 0:
            self.sdk.move_banknote_to_dispenser(banknote, used)
            self.banknotes_cache[banknote] -= used
            remaining -= used * banknote
        if remaining == 0:
            break

    self.sdk.open_dispenser()
    return True

**Объяснение:**
- Класс `ATM` принимает объект `SDK` для взаимодействия с аппаратной частью.
- Для оптимизации вызовов `count_banknotes` используется кэш, который обновляется перед выдачей.
- Метод `dispense` проверяет возможность выдать сумму, используя жадный алгоритм по номиналам.
- Если выдача возможна, банкноты перемещаются в диспенсер, после чего он открывается.
- Если сумма не кратна 50 или не может быть выдана, возвращается отказ.