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

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

6 точки общо

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

  1class Egg:
  2    def __init__(self):
  3        self._painted = 0.0
  4        self._segments = []
  5        self._broken_top = False
  6        self._broken_bottom = False
  7        self._tournament = None
  8
  9    def paint(self, *args):
 10        total = 0
 11        for _, percentage in args:
 12            total += percentage
 13        if self._painted + total > 100.0:
 14            raise ValueError("Egg overpainted")
 15        current = self._painted
 16        for hex_color, percentage in args:
 17            pigment = self._pigment_value(hex_color)
 18            start = current
 19            end = current + percentage
 20            self._segments.append((start, end, pigment))
 21            current = end
 22        self._painted = current
 23
 24    def __mul__(self, other):
 25        return self._battle(other, "top")
 26
 27    def __matmul__(self, other):
 28        return self._battle(other, "bottom")
 29
 30    def _battle(self, other, side):
 31        if side == "top":
 32            if self._broken_top or other._broken_top:
 33                raise TypeError("Broken side cannot be used again")
 34        else:
 35            if self._broken_bottom or other._broken_bottom:
 36                raise TypeError("Broken side cannot be used again")
 37        my_strength = self._side_strength(side)
 38        other_strength = other._side_strength(side)
 39        if my_strength > other_strength:
 40            winner = self
 41            loser = other
 42        else:
 43            winner = other
 44            loser = self
 45        if side == "top":
 46            loser._broken_top = True
 47        else:
 48            loser._broken_bottom = True
 49        if self._tournament is not None:
 50            if self._tournament is other._tournament:
 51                if self in self._tournament and other in self._tournament:
 52                    self._tournament._record_battle(self, other, side, winner)
 53        return winner
 54
 55    def _side_strength(self, side):
 56        if side == "top":
 57            start, end = 0.0, 50.0
 58        else:
 59            start, end = 50.0, 100.0
 60        pigment_sum = 0.0
 61        coverage = 0.0
 62        for seg_start, seg_end, pigment in self._segments:
 63            overlap_start = max(start, seg_start)
 64            overlap_end = min(end, seg_end)
 65            if overlap_start < overlap_end:
 66                overlap = overlap_end - overlap_start
 67                pigment_sum += overlap * pigment
 68                coverage += overlap
 69        return pigment_sum, coverage
 70
 71    @staticmethod
 72    def _pigment_value(hex_color):
 73        hex_color = hex_color.upper()
 74        r = int(hex_color[0:2], 16)
 75        g = int(hex_color[2:4], 16)
 76        b = int(hex_color[4:6], 16)
 77        return r + g + b
 78
 79
 80class EggTournament:
 81    def __init__(self):
 82        self._eggs_by_name = {}
 83        self._names_by_egg = {}
 84        self._victories = {}
 85        self._history = {}
 86
 87    def register(self, egg, name):
 88        if not name.isidentifier():
 89            raise ValueError("Invalid registration name")
 90        if egg._tournament is not None:
 91            if egg._tournament is not self:
 92                raise ValueError("An egg cannot be registered in multiple tournaments")
 93            if egg in self._names_by_egg:
 94                raise ValueError("An egg cannot be registered in multiple tournaments")
 95        if name in self._eggs_by_name:
 96            raise ValueError(f"Egg with name {name} has already been registered")
 97        self._eggs_by_name[name] = egg
 98        self._names_by_egg[egg] = name
 99        self._victories[egg] = 0
100        egg._tournament = self
101
102    def _record_battle(self, egg1, egg2, side, winner):
103        key = (frozenset((egg1, egg2)), side)
104        self._history[key] = winner
105        if winner in self._victories:
106            self._victories[winner] += 1
107
108    def __getitem__(self, key):
109        if isinstance(key, slice):
110            egg1, egg2, side = key.start, key.stop, key.step
111        else:
112            egg1, egg2, side = key[0], key[1], key[2]
113        history_key = (frozenset((egg1, egg2)), side)
114        if history_key not in self._history:
115            raise KeyError("No such battle found")
116        return self._history[history_key]
117
118    def __rmatmul__(self, position):
119        ranking = self._ranking()
120        if position not in ranking:
121            raise IndexError("No eggs at this position")
122        eggs = ranking[position]
123        if len(eggs) == 1:
124            for egg in eggs:
125                return egg
126        return eggs
127
128    def __getattr__(self, name):
129        if name in self._eggs_by_name:
130            egg = self._eggs_by_name[name]
131            victories = self._victories[egg]
132            position = self._position_of(egg)
133            return {"position": position, "victories": victories}
134        raise AttributeError("Apologies, there is no such egg registered")
135
136    def __contains__(self, egg):
137        return egg in self._names_by_egg
138
139    def _ranking(self):
140        by_wins = {}
141        for egg, wins in self._victories.items():
142            if wins not in by_wins:
143                by_wins[wins] = set()
144            by_wins[wins].add(egg)
145        sorted_wins = sorted(by_wins.keys(), reverse=True)
146        ranking = {}
147        position = 1
148        for wins in sorted_wins:
149            ranking[position] = by_wins[wins]
150            position += 1
151        return ranking
152
153    def _position_of(self, target_egg):
154        ranking = self._ranking()
155        for position, eggs in ranking.items():
156            if target_egg in eggs:
157                return position

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

OK

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