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

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

6 точки общо

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

  1def hex_to_degit(hex_digit):
  2    if hex_digit in {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}:
  3        return int(hex_digit)
  4    if hex_digit.lower() == "a":
  5        return 10
  6    if hex_digit.lower() == "b":
  7        return 11
  8    if hex_digit.lower() == "c":
  9        return 12
 10    if hex_digit.lower() == "d":
 11        return 13
 12    if hex_digit.lower() == "e":
 13        return 14
 14    if hex_digit.lower() == "f":
 15        return 15
 16
 17def hex_to_decimal(hex_number):
 18    return hex_to_degit(hex_number[0]) * 16 + hex_to_degit(hex_number[1])
 19
 20def hex_color_to_toughness(hex_color):
 21    return hex_to_decimal(hex_color[0:2]) + hex_to_decimal(hex_color[2:4]) + hex_to_decimal(hex_color[4:6])
 22
 23class Egg:
 24    def __init__(self):
 25        self.top_colors = {}
 26        self.bottom_colors = {}
 27        self.is_top_broken = False
 28        self.is_bottom_broken = False
 29        self.tournament = None
 30
 31    def paint(self, *args):
 32        if sum((percentage for hex_color, percentage in args)) + sum(self.top_colors.values()) + sum(self.bottom_colors.values()) > 100:
 33            raise ValueError("Colored more than 100%")
 34            
 35        for hex_color, percentage in args:
 36            top_percantage = sum(self.top_colors.values())
 37            if top_percantage >= 50:
 38                self._add_color_to_side(hex_color, percentage, "bottom")
 39            else:
 40                if top_percantage + percentage <= 50:
 41                    self._add_color_to_side(hex_color, percentage, "top")
 42                else:
 43                    added_to_top = 50 - top_percantage
 44                    self._add_color_to_side(hex_color, added_to_top, "top")
 45                    self._add_color_to_side(hex_color, percentage - added_to_top, "bottom")
 46
 47    def __mul__(self, other):
 48        if self.is_top_broken or other.is_top_broken:
 49            raise TypeError("The top of one of the eggs is already broken")
 50
 51        if not other.top_colors or self._toughness("top") > other._toughness("top"):
 52            other.is_top_broken = True
 53            winner = self
 54        else:
 55            self.is_top_broken = True
 56            winner = other
 57
 58        self.__class__._record_victory(self, other, winner, "top")
 59        return winner
 60
 61    def __matmul__(self, other):
 62        if self.is_bottom_broken or other.is_bottom_broken:
 63            raise TypeError("The bottom of one of the eggs is already broken")
 64
 65        if not other.bottom_colors or self._toughness("bottom") > other._toughness("bottom"):
 66            other.is_bottom_broken = True
 67            winner = self
 68        else:
 69            self.is_bottom_broken = True
 70            winner = other
 71
 72        self.__class__._record_victory(self, other, winner, "bottom")
 73        return winner
 74
 75    @staticmethod
 76    def _record_victory(egg1, egg2, winner, side):
 77        if egg1.tournament and egg2.tournament and egg1.tournament is egg2.tournament:
 78            winner.tournament.history[(egg1, egg2, side)] = winner
 79            winner.tournament.history[(egg2, egg1, side)] = winner
 80            if winner not in winner.tournament.egg_victories:
 81                winner.tournament.egg_victories[winner] = 0
 82            winner.tournament.egg_victories[winner] += 1
 83
 84    def _add_color_to_side(self, hex_color, percentage, side):
 85        if side == "top":
 86            if hex_color.lower() not in self.top_colors:
 87                self.top_colors[hex_color.lower()] = percentage
 88            else:
 89                self.top_colors[hex_color.lower()] += percentage
 90        if side == "bottom":
 91            if hex_color.lower() not in self.bottom_colors:
 92                self.bottom_colors[hex_color.lower()] = percentage
 93            else:
 94                self.bottom_colors[hex_color.lower()] += percentage
 95
 96    def _toughness(self, side):
 97        if side == "top":
 98            return sum(hex_color_to_toughness(hex_color) * percentage for hex_color, percentage in self.top_colors.items())
 99        if side == "bottom":
100            return sum(hex_color_to_toughness(hex_color) * percentage for hex_color, percentage in self.bottom_colors.items())
101
102
103class EggTournament:
104    def __init__(self):
105        self.eggs = {}
106        self.history = {}
107        self.egg_victories = {}
108
109    def register(self, egg, alias):
110        if not alias.isidentifier():
111            raise ValueError("Invalid registration name")
112
113        if alias in self.eggs:
114            raise ValueError(f"Egg with name {alias} has already been registered")
115
116        if egg.tournament is not None:
117            raise ValueError("An egg cannot be registered in multiple tournaments")
118
119        self.eggs[alias] = egg
120        self.egg_victories[egg] = 0
121        egg.tournament = self
122
123    def get_ranking(self):
124        eggs = sorted(self.egg_victories.items(), key=lambda x: -x[1])
125
126        ranking = {}
127        current_rank = 0
128        last_score = -1
129
130        for egg, score in eggs:
131            if score != last_score:
132                current_rank += 1
133                last_score = score
134
135            if current_rank not in ranking:
136                ranking[current_rank] = set()
137            ranking[current_rank].add(egg)
138
139        return ranking
140    
141    def __rmatmul__(self, position):
142        ranking = self.get_ranking()
143
144        if position not in ranking:
145            raise IndexError("There is no such position in the ranking")
146
147        eggs = ranking[position]
148        if len(eggs) == 1:
149            return eggs.pop()
150        return eggs
151    
152    def __getitem__(self, key):
153        if isinstance(key, tuple):
154            egg1, egg2, position = key
155        elif isinstance(key, slice):
156            egg1 = key.start
157            egg2 = key.stop
158            position = key.step
159        else:
160            raise KeyError("Invalid key")
161
162        if (egg1, egg2, position) in self.history:
163            return self.history[(egg1, egg2, position)]
164        raise KeyError("No clash found")
165
166    def __getattr__(self, alias):
167        if alias in self.eggs:
168            egg = self.eggs[alias]
169            ranking = self.get_ranking()
170            for position, eggs in ranking.items():
171                if egg in eggs:
172                    return {
173                        "position": position,
174                        "victories": self.egg_victories[egg],
175                    }
176        raise AttributeError("Apologies, there is no such egg registered")
177
178    def __contains__(self, egg):
179        return egg in self.eggs.values()

..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.002s

OK

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