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

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

6 точки общо

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

  1EPS = 1e-9
  2
  3class Egg:
  4    def __init__(self):
  5        self.colors = []
  6        self.top_broken = False
  7        self.bottom_broken = False
  8        self.tournament = None
  9
 10    def paint(self, *args):
 11        if sum(percentage for color, percentage in self.colors) + sum(percentage for color, percentage in args) > 100 + EPS:
 12            raise ValueError("Paint is more than 100%")
 13        for hex_color, percentage in args:
 14            self.colors.append((hex_color.upper(), percentage))
 15    
 16    def _count_strength(self, start, end):
 17        total = 0.0
 18        filled = 0.0
 19        has_paint = False
 20        for hex_color, percentage in self.colors:
 21            segment_start = filled
 22            segment_end = filled + percentage
 23            part_percentage = max(0, min(segment_end, end) - max(segment_start, start))
 24            if part_percentage > 0:
 25                has_paint = True
 26                total += (int(hex_color[:2], 16) + int(hex_color[2:4], 16) + int(hex_color[4:], 16)) * (part_percentage / 50)
 27            filled = segment_end
 28        return total, has_paint
 29    
 30    def _top_strength(self):
 31        return self._count_strength(0, 50)
 32    
 33    def _bottom_strength(self):
 34        return self._count_strength(50, 100)
 35    
 36    def __mul__(self, other):
 37        if self.top_broken or other.top_broken:
 38            raise TypeError("Top side already broken")
 39        my_strength, my_painted = self._top_strength()
 40        other_strength, other_painted = other._top_strength()
 41        if not my_painted and other_painted:
 42            self.top_broken = True
 43            winner = other
 44        elif not other_painted and my_painted:
 45            other.top_broken = True
 46            winner = self
 47        elif my_strength > other_strength:
 48            other.top_broken = True
 49            winner = self
 50        else:
 51            self.top_broken = True
 52            winner = other
 53        if self.tournament and self.tournament is other.tournament:
 54            self.tournament.record_battle(self, other, "top", winner)
 55        return winner
 56    
 57    def __matmul__(self, other):
 58        if self.bottom_broken or other.bottom_broken:
 59            raise TypeError("Bottom side already broken")
 60        my_strength, my_painted = self._bottom_strength()
 61        other_strength, other_painted = other._bottom_strength()
 62        if not my_painted and other_painted:
 63            self.bottom_broken = True
 64            winner = other
 65        elif not other_painted and my_painted:
 66            other.bottom_broken = True
 67            winner = self
 68        elif my_strength > other_strength:
 69            other.bottom_broken = True
 70            winner = self
 71        else:
 72            self.bottom_broken = True
 73            winner = other
 74        if self.tournament and self.tournament is other.tournament:
 75            self.tournament.record_battle(self, other, "bottom", winner)
 76        return winner
 77    
 78
 79class EggTournament:
 80    def __init__(self):
 81        self._eggs = {}
 82        self._wins = {}
 83        self._history = {}
 84
 85    def register(self, egg, name):
 86        if egg.tournament is not None:
 87            raise ValueError("An egg cannot be registered in multiple tournaments")
 88        if not name.isidentifier():
 89            raise ValueError("Invalid registration name")
 90        if name in self._eggs:
 91            raise ValueError(f"Egg with name {name} has already been registered")
 92        self._eggs[name] = egg
 93        self._wins[egg] = 0
 94        egg.tournament = self
 95
 96    def record_battle(self, egg1, egg2, side, winner):
 97        if egg1 not in self or egg2 not in self:
 98            return
 99        self._history[(frozenset((egg1, egg2)), side)] = winner
100        self._wins[winner] += 1
101
102    def __getitem__(self, key):
103        if isinstance(key, tuple):
104            egg1, egg2, side = key
105        elif isinstance(key, slice):
106            egg1, egg2, side = key.start, key.stop, key.step
107        else:
108            raise KeyError
109        pair = frozenset((egg1, egg2))
110        if (pair, side) not in self._history:
111            raise KeyError("No match found")
112        return self._history[(pair, side)]
113    
114    def _ranking(self):
115        sorted_eggs = sorted(self._wins.items(), key=lambda pair: pair[1], reverse=True)
116        ranking = {}
117        current_position = 1
118        previous_wins = None
119        for egg, wins in sorted_eggs:
120            if previous_wins is None:
121                ranking[egg] = current_position
122            elif wins < previous_wins:
123                current_position += 1
124                ranking[egg] = current_position
125            else:
126                ranking[egg] = current_position
127            previous_wins = wins
128        return ranking
129    
130    def __rmatmul__(self, position):
131        ranking = self._ranking()
132        result = {egg for egg, pos in ranking.items() if pos == position}
133        if not result:
134            raise IndexError("No such rank")
135        if len(result) == 1:
136            return next(iter(result))
137        return result
138
139    def __getattr__(self, name):
140        if name not in self._eggs:
141            raise AttributeError("Apologies, there is no such egg registered")
142        egg = self._eggs[name]
143        ranking = self._ranking()
144        return {"position": ranking[egg], "victories": self._wins[egg]}
145
146    def __contains__(self, egg):
147        return egg in self._eggs.values()
148    

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

OK

Дискусия
История
Това решение има само една версия.