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

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

6 точки общо

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

  1class Egg:
  2    def __init__(self):
  3        self.layers = []
  4        self.filled = 0.0
  5        self.top_broken = False
  6        self.bottom_broken = False
  7        self.tournament = None
  8
  9    def _hex_to_value(self, hex_color):
 10        hex_color = hex_color.upper()
 11        r = int(hex_color[0:2], 16)
 12        g = int(hex_color[2:4], 16)
 13        b = int(hex_color[4:6], 16)
 14        return r + g + b
 15
 16    def paint(self, *args):
 17        total = sum(p for _, p in args)
 18        if round(self.filled + total, 6) > 100:
 19            raise ValueError()
 20        for color, percentage in args:
 21            value = self._hex_to_value(color)
 22            self.layers.append((value, percentage))
 23            self.filled += percentage
 24
 25    def _get_half_value(self, top=True):
 26        target_start = 0 if top else 50
 27        target_end = 50 if top else 100
 28        current = 0
 29        total_value = 0
 30        total_coverage = 0
 31        for value, perc in self.layers:
 32            next_pos = current + perc
 33
 34            overlap_start = max(current, target_start)
 35            overlap_end = min(next_pos, target_end)
 36
 37            if overlap_start < overlap_end:
 38                portion = overlap_end - overlap_start
 39                total_value += value * portion
 40                total_coverage += portion
 41
 42            current = next_pos
 43        return (total_value, total_coverage)
 44
 45    def _fight(self, other, top=True):
 46        if top:
 47            if self.top_broken or other.top_broken:
 48                raise TypeError("Egg side is already broken.")
 49        else:
 50            if self.bottom_broken or other.bottom_broken:
 51                raise TypeError("Egg side is already broken.")
 52
 53        my_val = self._get_half_value(top)
 54        other_val = other._get_half_value(top)
 55        if my_val > other_val:
 56            loser = other
 57            winner = self
 58        else:
 59            loser = self
 60            winner = other
 61
 62        if top:
 63            loser.top_broken = True
 64        else:
 65            loser.bottom_broken = True
 66
 67        if self.tournament and self.tournament == other.tournament:
 68            self.tournament._record(self, other, top, winner)
 69
 70        return winner
 71
 72    def __mul__(self, other):
 73        return self._fight(other, top=True)
 74
 75    def __matmul__(self, other):
 76        return self._fight(other, top=False)
 77
 78
 79class EggTournament:
 80    def __init__(self):
 81        self.eggs = {}
 82        self.names = {}
 83        self.victories = {}
 84        self.history = []
 85
 86    def register(self, egg, name):
 87        if not name.isidentifier():
 88            raise ValueError("Invalid registration name")
 89
 90        if name in self.names:
 91            raise ValueError(f"Egg with name {name} has already been registered")
 92
 93        if egg.tournament is not None:
 94            raise ValueError("An egg cannot be registered in multiple tournaments")
 95
 96        self.eggs[egg] = name
 97        self.names[name] = egg
 98        self.victories[egg] = 0
 99        egg.tournament = self
100
101    def _record(self, egg1, egg2, top, winner):
102        side = "top" if top else "bottom"
103        self.history.append((frozenset([egg1, egg2]), side, winner))
104        if winner in self.victories:
105            self.victories[winner] += 1
106
107    def __getitem__(self, key):
108        if isinstance(key, tuple):
109            egg1, egg2, side = key
110        else:
111            egg1, egg2, side = key.start, key.stop, key.step
112
113        for pair, s, winner in self.history:
114            if pair == frozenset([egg1, egg2]) and s == side:
115                return winner
116
117        raise KeyError()
118
119    def __rmatmul__(self, position):
120        sorted_eggs = sorted(self.victories.items(), key=lambda x: -x[1])
121
122        ranks = {}
123        current_rank = 0
124        last_score = None
125
126        for egg, score in sorted_eggs:
127            if score != last_score:
128                current_rank += 1
129                last_score = score
130            ranks.setdefault(current_rank, set()).add(egg)
131
132        if position not in ranks:
133            raise IndexError("Position out of bounds")
134
135        res = ranks[position]
136        return res if len(res) > 1 else next(iter(res))
137
138    def __getattr__(self, name):
139        names = self.__dict__.get("names", {})
140        if name not in names:
141            raise AttributeError("Apologies, there is no such egg registered")
142        egg = names[name]
143        victories = self.__dict__.get("victories", {})
144        wins = victories.get(egg, 0)
145        sorted_scores = sorted(set(victories.values()), reverse=True)
146        position = sorted_scores.index(wins) + 1
147        return {"position": position, "victories": wins}
148
149    def __contains__(self, egg):
150        return egg in self.eggs

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

OK

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