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

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

6 точки общо

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

  1class Egg:
  2
  3    def __init__(self):
  4        self.colors = []
  5        self.total_percentage = 0
  6        self.top_cracked = False
  7        self.bottom_cracked = False
  8        self.tournament = None
  9
 10    def paint(self, *args):
 11
 12        new_percentage = 0
 13
 14        for hex_color, percentage in args:
 15            new_percentage += percentage
 16
 17        if self.total_percentage + new_percentage > 100:
 18            raise ValueError
 19
 20        self.colors.extend((hex_color.upper(), percentage) for hex_color, percentage in args)
 21        self.total_percentage += new_percentage
 22
 23    def hex_color_value(self, hex_color):
 24
 25        first_hex_pair = hex_color[0:2]
 26        second_hex_pair = hex_color[2:4]
 27        third_hex_pair = hex_color[4:6]
 28
 29        sum_hex_color_value =  int(first_hex_pair, 16) + int(second_hex_pair, 16) + int(third_hex_pair, 16)
 30
 31        return sum_hex_color_value
 32
 33    def overlap(self, start1, end1, start2, end2):
 34
 35        return max(0, min(end1, end2) - max(start1, start2))
 36
 37    def egg_half_values(self):
 38
 39        current_position = 0
 40        top_value = 0
 41        bottom_value = 0
 42
 43        for hex_color, percentage in self.colors:
 44            start_position = current_position
 45            end_position = start_position + percentage
 46
 47            raw_pigment_value = self.hex_color_value(hex_color)
 48            pigment_value = raw_pigment_value if raw_pigment_value != 0 else 1
 49            top_part = self.overlap(start_position, end_position, 0, 50)
 50            bottom_part = self.overlap(start_position, end_position, 50, 100)
 51
 52            top_value += top_part * pigment_value / 50
 53            bottom_value += bottom_part * pigment_value / 50
 54
 55            current_position = end_position
 56
 57        return top_value, bottom_value
 58
 59    def __mul__(self, other):
 60
 61        if self.top_cracked or other.top_cracked:
 62            raise TypeError
 63
 64        my_top_value = self.egg_half_values()[0]
 65        other_top_value = other.egg_half_values()[0]
 66
 67        if my_top_value > other_top_value:
 68            other.top_cracked = True
 69            winner = self
 70        else:
 71            self.top_cracked = True
 72            winner = other
 73
 74        if self.tournament is not None and self.tournament is other.tournament:
 75            self.tournament.record_match(self, other, "top", winner)
 76
 77        return winner
 78
 79    def __matmul__(self, other):
 80
 81        if self.bottom_cracked or other.bottom_cracked:
 82            raise TypeError
 83
 84        my_bottom_value = self.egg_half_values()[1]
 85        other_bottom_value = other.egg_half_values()[1]
 86
 87        if my_bottom_value > other_bottom_value:
 88            other.bottom_cracked = True
 89            winner =  self
 90        else:
 91            self.bottom_cracked = True
 92            winner = other
 93
 94        if self.tournament is not None and self.tournament is other.tournament:
 95            self.tournament.record_match(self, other, "bottom", winner)
 96
 97        return winner
 98
 99class EggTournament:
100
101    def __init__(self):
102        self.egg_to_name = {}
103        self.name_to_egg = {}
104        self.victories = {}
105        self.matches = {}
106
107    def register(self, egg, name):
108
109        if not name.isidentifier():
110            raise ValueError("Invalid registration name")
111
112        if egg.tournament is not None:
113            raise ValueError("An egg cannot be registered in multiple tournaments")
114
115        if name in self.name_to_egg:
116            raise ValueError(f"Egg with name {name} has already been registered")
117
118        self.egg_to_name[egg] = name
119        self.name_to_egg[name] = egg
120        self.victories[egg] = 0
121        egg.tournament = self
122
123    def __contains__(self, egg):
124        return egg in self.egg_to_name
125
126    def get_position(self, egg):
127
128        egg_victories = self.victories[egg]
129        count_position = 0
130
131        for victories in set(self.victories.values()):
132            count_position += 1 if victories > egg_victories else 0
133
134        return count_position + 1
135
136    def __getattr__(self, name):
137
138        if name not in self.name_to_egg:
139            raise AttributeError("Apologies, there is no such egg registered")
140
141        egg = self.name_to_egg[name]
142
143        return {
144            "position": self.get_position(egg),
145            "victories": self.victories[egg]
146        }
147
148    def record_match(self, egg1, egg2, side, winner):
149
150        self.matches[(frozenset({egg1, egg2}), side)] = winner
151        self.victories[winner] += 1
152
153    def __getitem__(self, key):
154
155        if isinstance(key, tuple):
156            egg1, egg2, side = key
157        elif isinstance(key, slice):
158            egg1, egg2, side = key.start, key.stop, key.step
159        else:
160            raise KeyError
161
162        match_key = (frozenset({egg1, egg2}), side)
163
164        if match_key not in self.matches:
165            raise KeyError
166
167        return self.matches[match_key]
168
169    def __rmatmul__(self, position):
170        eggs_at_position = {egg for egg in self.victories if self.get_position(egg) == position}
171
172        if not eggs_at_position:
173            raise IndexError
174
175        if len(eggs_at_position) == 1:
176            return next(iter(eggs_at_position))
177
178        return eggs_at_position

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

OK

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