1class RunewordsCalculator:
2 def __init__(self, runewords: dict):
3 self._runewords = runewords
4 self._runes = []
5 self._made_runewords = set()
6
7 def add_runes(self, runes):
8 self._runes.extend(runes)
9
10 def __iter__(self):
11 return self
12
13 def _can_craft(self, recipe):
14 available = list(self._runes)
15 used_rune_indices = []
16 search_from = 0
17 for rune in recipe:
18 try:
19 rune_idx = available.index(rune, search_from)
20 used_rune_indices.append(rune_idx)
21 search_from = rune_idx + 1
22 except ValueError:
23 return None
24 return used_rune_indices
25
26 def __next__(self):
27 if len(self._made_runewords) == len(self._runewords):
28 raise StopIteration
29 for name, recipe in self._runewords.items():
30 if name not in self._made_runewords:
31 used_rune_indices = self._can_craft(recipe)
32 if used_rune_indices is not None:
33 self._made_runewords.add(name)
34 for rune_idx in sorted(used_rune_indices, reverse=True):
35 self._runes.pop(rune_idx)
36 return name
37 return None
.....F.
======================================================================
FAIL: test_returns_runewords_in_runeword_order (test.TestRunewordsCalculator.test_returns_runewords_in_runeword_order)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 55, in test_returns_runewords_in_runeword_order
self.assertEqual(next(iterator), "First")
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: None != 'First'
----------------------------------------------------------------------
Ran 7 tests in 0.001s
FAILED (failures=1)
| f | 1 | class RunewordsCalculator: | f | 1 | class RunewordsCalculator: |
| 2 | def __init__(self, runewords: dict): | 2 | def __init__(self, runewords: dict): | ||
| 3 | self._runewords = runewords | 3 | self._runewords = runewords | ||
| 4 | self._runes = [] | 4 | self._runes = [] | ||
| 5 | self._made_runewords = set() | 5 | self._made_runewords = set() | ||
| 6 | 6 | ||||
| 7 | def add_runes(self, runes): | 7 | def add_runes(self, runes): | ||
| 8 | self._runes.extend(runes) | 8 | self._runes.extend(runes) | ||
| t | 9 | t | |||
| 10 | 9 | ||||
| 11 | def __iter__(self): | 10 | def __iter__(self): | ||
| 12 | return self | 11 | return self | ||
| 13 | 12 | ||||
| 14 | def _can_craft(self, recipe): | 13 | def _can_craft(self, recipe): | ||
| 15 | available = list(self._runes) | 14 | available = list(self._runes) | ||
| 16 | used_rune_indices = [] | 15 | used_rune_indices = [] | ||
| 17 | search_from = 0 | 16 | search_from = 0 | ||
| 18 | for rune in recipe: | 17 | for rune in recipe: | ||
| 19 | try: | 18 | try: | ||
| 20 | rune_idx = available.index(rune, search_from) | 19 | rune_idx = available.index(rune, search_from) | ||
| 21 | used_rune_indices.append(rune_idx) | 20 | used_rune_indices.append(rune_idx) | ||
| 22 | search_from = rune_idx + 1 | 21 | search_from = rune_idx + 1 | ||
| 23 | except ValueError: | 22 | except ValueError: | ||
| 24 | return None | 23 | return None | ||
| 25 | return used_rune_indices | 24 | return used_rune_indices | ||
| 26 | 25 | ||||
| 27 | def __next__(self): | 26 | def __next__(self): | ||
| 28 | if len(self._made_runewords) == len(self._runewords): | 27 | if len(self._made_runewords) == len(self._runewords): | ||
| 29 | raise StopIteration | 28 | raise StopIteration | ||
| 30 | for name, recipe in self._runewords.items(): | 29 | for name, recipe in self._runewords.items(): | ||
| 31 | if name not in self._made_runewords: | 30 | if name not in self._made_runewords: | ||
| 32 | used_rune_indices = self._can_craft(recipe) | 31 | used_rune_indices = self._can_craft(recipe) | ||
| 33 | if used_rune_indices is not None: | 32 | if used_rune_indices is not None: | ||
| 34 | self._made_runewords.add(name) | 33 | self._made_runewords.add(name) | ||
| 35 | for rune_idx in sorted(used_rune_indices, reverse=True): | 34 | for rune_idx in sorted(used_rune_indices, reverse=True): | ||
| 36 | self._runes.pop(rune_idx) | 35 | self._runes.pop(rune_idx) | ||
| 37 | return name | 36 | return name | ||
| 38 | return None | 37 | return None |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||