| f | from collections import Counter | f | from collections import Counter |
| | | |
| class RunewordsCalculator: | | class RunewordsCalculator: |
| def __init__(self, runewords : dict[str, list | tuple [str]]): | | def __init__(self, runewords : dict[str, list | tuple [str]]): |
| self.__runewords_recepies = runewords | | self.__runewords_recepies = runewords |
| self.__runes = [] | | self.__runes = [] |
| self.__used = set() | | self.__used = set() |
| | | |
| def add_runes(self, runes : tuple | list [str]) -> None: | | def add_runes(self, runes : tuple | list [str]) -> None: |
| self.__runes.extend(runes) | | self.__runes.extend(runes) |
| | | |
| def __use_runes(self, used_runes : iter[str]) -> None: | | def __use_runes(self, used_runes : iter[str]) -> None: |
| new_runes = [] | | new_runes = [] |
| used_rune = next(used_runes) | | used_rune = next(used_runes) |
| for founded_rune in self.__runes: | | for founded_rune in self.__runes: |
| if used_rune == founded_rune: | | if used_rune == founded_rune: |
| try: | | try: |
| used_rune = next(used_runes) | | used_rune = next(used_runes) |
| except StopIteration: | | except StopIteration: |
| used_rune = None | | used_rune = None |
| continue | | continue |
| else: | | else: |
| new_runes.append(founded_rune) | | new_runes.append(founded_rune) |
| self.__runes = new_runes | | self.__runes = new_runes |
| return None | | return None |
| | | |
| | | |
| def __cooking_runewords(self, recipe : iter[str]) -> bool: | | def __cooking_runewords(self, recipe : iter[str]) -> bool: |
| try: | | try: |
| needed_rune = next(recipe) | | needed_rune = next(recipe) |
| for founded_rune in self.__runes: | | for founded_rune in self.__runes: |
| if needed_rune == founded_rune: | | if needed_rune == founded_rune: |
| needed_rune = next(recipe) | | needed_rune = next(recipe) |
| return False | | return False |
| except StopIteration: | | except StopIteration: |
| return True | | return True |
| | | |
| def __iter__(self): | | def __iter__(self): |
| return self | | return self |
| | | |
| def __next__(self): | | def __next__(self): |
| if all(runeword in self.__used for runeword in self.__runewords_recepies.keys()): | | if all(runeword in self.__used for runeword in self.__runewords_recepies.keys()): |
| raise StopIteration | | raise StopIteration |
| | | |
| for runeword, recipe in self.__runewords_recepies.items(): | | for runeword, recipe in self.__runewords_recepies.items(): |
| if runeword in self.__used: | | if runeword in self.__used: |
| continue | | continue |
| elif self.__cooking_runewords((rune for rune in recipe)): | | elif self.__cooking_runewords((rune for rune in recipe)): |
| self.__use_runes((rune for rune in recipe)) | | self.__use_runes((rune for rune in recipe)) |
| self.__used.add(runeword) | | self.__used.add(runeword) |
| return runeword | | return runeword |
| return None | | return None |
| t | | t | |
| | | |
| calculator = RunewordsCalculator({ | | |
| "X": ("A", "A") | | |
| }) | | |
| | | |
| calculator.add_runes(["A", "B", "A"]) | | |
| | | |
| print(next(iter(calculator))) # X (ползва A, B) | | |
| print(next(iter(calculator))) # None (остава само C) | | |
| | | |
| calculator.add_runes(["A", "A"]) | | |
| | | |
| print(next(iter(calculator))) # Y или Z (зависи от реда) | | |
| print(calculator._RunewordsCalculator__runes) | | |