Домашни > Великденско домашно > Решения > Решението на Коста Илев

Резултати
6 точки от тестове
1 точки от учител

7 точки общо

46 успешни теста
0 неуспешни теста
Код
Скрий всички коментари

  1class Egg:
  2    def __init__(self):
  3        self.percentage_painted = 0
  4        self.colors = []
  5        self.upper_broken = False
  6        self.lower_broken = False
  7
  8    def paint(self, *pairs):
  9        added_percentage = sum(percentage for hex_color, percentage in pairs)
 10        if self.percentage_painted + added_percentage > 100:
 11            raise ValueError("Cannot paint the egg more than 100%!")
 12        for hex_color, percentage in pairs:
 13            self.colors.append((hex_color.lower(), percentage))
 14        self.percentage_painted += added_percentage
 15
 16    def color_durability(self, hex_color):
 17        r = int(hex_color[0:2], 16)
 18        g = int(hex_color[2:4], 16)
 19        b = int(hex_color[4:6], 16)
 20        return r + g + b
 21    
 22    @property
 23    def _upper_durability(self):
 24        if self.percentage_painted == 0:
 25            return -1
 26        current_procentage = 0
 27        durability = 0
 28        for hex_color, percentage in self.colors:
 29            if current_procentage + percentage > 50:
 30                durability += (50 - current_procentage) * self.color_durability(hex_color)
 31                return durability
 32            durability += percentage * self.color_durability(hex_color)
 33            current_procentage += percentage
 34        return durability
 35    
 36    @property
 37    def _lower_durability(self):
 38        if self.percentage_painted <= 50:
 39            return -1
 40        current_procentage = 0
 41        durability = 0
 42        max_procentage = self.percentage_painted - 50
 43        for hex_color, percentage in self.colors[::-1]:
 44            if current_procentage + percentage > max_procentage:
 45                durability += (max_procentage - current_procentage) * self.color_durability(hex_color)
 46                return durability
 47            durability += percentage * self.color_durability(hex_color)
 48            current_procentage += percentage
 49        return durability
 50    
 51    def __mul__(self, other):
 52        if self.upper_broken:
 53            raise TypeError("This egg's upper side is already broken!")
 54        if other.upper_broken:
 55            raise TypeError("The other egg's upper side is already broken!")
 56        winner = self if self._upper_durability >= other._upper_durability else other
 57        loser = other if winner is self else self
 58        loser.upper_broken = True
 59        if hasattr(self, 'tournament'):
 60            self.tournament.record(self, other, "top", winner)
 61        return winner
 62    
 63    def __matmul__(self, other):
 64        if self.lower_broken:
 65            raise TypeError("This egg's lower side is already broken!")
 66        if other.lower_broken:
 67            raise TypeError("The other egg's lower side is already broken!")
 68        winner = self if self._lower_durability >= other._lower_durability else other
 69        loser = other if winner is self else self
 70        loser.lower_broken = True
 71        if hasattr(self, 'tournament'):
 72            self.tournament.record(self, other, "bottom", winner)
 73        return winner
 74             
 75
 76class EggTournament:
 77    def __init__(self):
 78        self.eggs = {}  
 79        self.history = []
 80
 81    def register(self, egg, name):
 82        if not name.isidentifier():
 83            raise ValueError("Invalid registration name")
 84        if hasattr(egg, 'tournament'):
 85            raise ValueError("An egg cannot be registered in multiple tournaments")
 86        if name in self.eggs:
 87            raise ValueError(f"Egg with name {name} has already been registered")
 88        egg.tournament = self
 89        self.eggs[name] = egg
 90
 91    def record(self, egg1, egg2, side, winner):
 92        registered = set(self.eggs.values())
 93        if egg1 in registered and egg2 in registered:
 94            self.history.append((egg1, egg2, side, winner))
 95
 96    def __getitem__(self, key):
 97        if isinstance(key, tuple):
 98            egg1, egg2, side = key
 99        elif isinstance(key, slice):
100            egg1, egg2, side = key.start, key.stop, key.step
101        else:
102            raise KeyError(key)
103        for h_egg1, h_egg2, h_side, winner in self.history:
104            if h_side == side and {h_egg1, h_egg2} == {egg1, egg2}:
105                return winner
106        raise KeyError(f"No match found between the two eggs on side '{side}'")
107    
108    def _get_wins(self): # Това исках да го направя с @property ама ми ставаха някакви безкрайни рекурсии от getattr
109        wins = {e: 0 for e in self.eggs.values()}
110        for h_egg1, h_egg2, h_side, winner in self.history:
111            if winner in wins:
112                wins[winner] += 1
113        return wins 
114
115    def __rmatmul__(self, position):
116        wins = self._get_wins()
117        sorted_wins = sorted(set(wins.values()), reverse=True)
118        if position > len(sorted_wins):
119            raise IndexError(f"No egg at position {position}")
120        target_wins = sorted_wins[position - 1]
121        result = {egg for egg, win_count in wins.items() if win_count == target_wins}
122        if len(result) == 1:
123            return next(iter(result))
124        return result
125
126    def __getattr__(self, name):
127        if name not in self.eggs:
128            raise AttributeError("Apologies, there is no such egg registered")
129        egg = self.eggs[name]
130        wins = self._get_wins()
131        egg_wins = wins[egg]
132        sorted_wins = sorted(set(wins.values()), reverse=True)
133        position = sorted_wins.index(egg_wins) + 1
134        return {"position": position, "victories": egg_wins}
135    
136    def __contains__(self, egg):
137        return egg in self.eggs.values()

..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.001s

OK

Дискусия
Виктор Бечев
15.04.2026 16:58

Като цяло - добре решение. Добрата структура на данните и property-тата ти прави живота лесен. Въпреки повторението на кода в `__mul__` и `__matmul__` ми се иска да те поощря. И тъй като няма да дойде ФМИ полицията - ще го направя. Печелиш бонус точка.
История
Това решение има само една версия.