1import keyword
2
3class Egg:
4
5 colored_percantage = 0
6
7 def __init__(self):
8 self.colored_percantage = 0
9 self.colors = []
10 self.sideA=0
11 self.sideB=0
12 self.sideA_broken = False
13 self.sideB_broken = False
14 self.tournament = None
15
16 def paint(self, *args):
17 total_percantage = sum(percentage for _, percentage in args)
18
19 if self.colored_percantage + total_percantage > 100:
20 raise ValueError("Яйцето не може да бъде бядисано на повече от 100%!")
21
22 for hex_color, percentage in args:
23 self.colors.append((hex_color.upper(),percentage))
24 self.colored_percantage += percentage
25 self.shell_strength()
26
27 def color_strength(self, color):
28 sum_colors = 0
29 while color != "":
30 rgb = color[-2:]
31 sum_colors += int(rgb,16)
32 color = color[:-2]
33 return sum_colors
34
35 def shell_strength(self):
36 curr_perc = 0
37 self.sideA = 0
38 self.sideB = 0
39 self.sideA_coverage = 0
40 self.sideB_coverage = 0
41
42 for hex_color, percentage in self.colors:
43 if curr_perc < 50 and curr_perc + percentage <= 50:
44 self.sideA += self.color_strength(hex_color) * percentage / 50
45 curr_perc += percentage
46 self.sideA_coverage += percentage
47 elif curr_perc < 50 and curr_perc + percentage >= 50:
48 top = 50 - curr_perc
49 bottom = percentage - top
50 self.sideA += self.color_strength(hex_color) * top / 50
51 self.sideA_coverage += top
52 self.sideB += self.color_strength(hex_color) * bottom / 50
53 self.sideB_coverage += bottom
54 curr_perc += percentage
55 else:
56 self.sideB += self.color_strength(hex_color) * percentage / 50
57 curr_perc += percentage
58 self.sideB_coverage += percentage
59
60 def set_tournament(self, tournament):
61 self.tournament = tournament
62
63 def top_power(self):
64 if self.sideA_coverage == 0:
65 return (-1, 0)
66 return (0, self.sideA)
67
68 def bottom_power(self):
69 if self.sideB_coverage == 0:
70 return (-1, 0)
71 return (0, self.sideB)
72
73 def __mul__(self, other):
74 if self.sideA_broken or other.sideA_broken:
75 raise TypeError("Някое яйце вече е счупено от тази страна")
76 winner = None
77 if self.top_power() > other.top_power():
78 other.sideA_broken = True
79 winner = self
80 else:
81 self.sideA_broken = True
82 winner = other
83 if self.tournament is not None and self.tournament is other.tournament:
84 self.tournament._register_battle(self, other, "top", winner)
85 return winner
86
87 def __matmul__(self, other):
88 if self.sideB_broken or other.sideB_broken:
89 raise TypeError("Някое яйце вече е счупено от тази страна")
90 winner = None
91 if self.bottom_power() > other.bottom_power():
92 other.sideB_broken = True
93 winner = self
94 else:
95 self.sideB_broken = True
96 winner = other
97 if self.tournament is not None and self.tournament is other.tournament:
98 self.tournament._register_battle(self, other, "bottom", winner)
99 return winner
100
101class EggTournament:
102 def __init__(self):
103 self.eggs = {}
104 self.history = {}
105 self.leaderboard = {}
106
107 def register(self, egg, nickname):
108 if nickname in self.eggs.values():
109 raise ValueError(f"Egg with name {nickname} has already been registered")
110 if egg.tournament is not None:
111 raise ValueError("An egg cannot be registered in multiple tournaments")
112 if not isinstance(nickname, str) or not nickname.isidentifier() or keyword.iskeyword(nickname):
113 raise ValueError("Invalid registration name")
114 self.eggs[egg] = nickname
115 self.leaderboard[egg] = 0
116 egg.set_tournament(self)
117
118 def _battle_key(self, egg1, egg2, position):
119 if id(egg1) < id(egg2):
120 return (egg1, egg2, position)
121 return (egg2, egg1, position)
122
123 def _register_battle(self, egg1, egg2, battle_type, winner):
124 if egg1 not in self.eggs or egg2 not in self.eggs:
125 return
126 key = self._battle_key(egg1, egg2, battle_type)
127 self.history[key] = winner
128 self.leaderboard[winner]+= 1
129
130 def __getitem__(self, item):
131 if isinstance(item, tuple):
132 egg1, egg2, battle_type = item
133 elif isinstance(item, slice):
134 egg1 = item.start
135 egg2 = item.stop
136 battle_type = item.step
137 else:
138 raise KeyError("Not given in the right format")
139 key = self._battle_key(egg1, egg2, battle_type)
140 if key in self.history:
141 return self.history[key]
142 else:
143 raise KeyError("No such battle")
144
145 def _ranking_by_position(self):
146 sorted_items = sorted( self.leaderboard.items(),
147 key=lambda x: x[1],
148 reverse=True
149 )
150
151 result = {}
152 current_rank = 0
153 last_score = None
154
155 for egg, wins in sorted_items:
156 if wins != last_score:
157 current_rank += 1
158 result[current_rank] = set()
159 last_score = wins
160
161 result[current_rank].add(egg)
162
163 return result
164
165 def __rmatmul__(self, index):
166 sorted_leaderboard = self._ranking_by_position()
167 if index not in sorted_leaderboard:
168 raise IndexError("Index doesn't exist in the leaderboard")
169 ranked = sorted_leaderboard[index]
170 if len(ranked) == 1:
171 return next(iter(ranked))
172 return ranked
173
174 def __getattr__(self, name):
175 for egg, nickname in self.eggs.items():
176 if nickname == name:
177 sorted_leaderboard = self._ranking_by_position()
178 vic = self.leaderboard[egg]
179 for position, eggs in sorted_leaderboard.items():
180 if egg in eggs:
181 return {"position": position, "victories": vic}
182
183 raise AttributeError("Apologies, there is no such egg registered")
184
185 def __contains__(self, item):
186 return item in self.eggs
.....................E........................
======================================================================
ERROR: test_unpainted_half_loses_to_half_painted_black (test.TestEgg.test_unpainted_half_loses_to_half_painted_black)
An unpainted half should lose to a half painted in black.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 200, in test_unpainted_half_loses_to_half_painted_black
self.assertIs(unpainted_egg * black_egg, black_egg)
~~~~~~~~~~~~~~^~~~~~~~~~~
File "/tmp/solution.py", line 77, in __mul__
if self.top_power() > other.top_power():
~~~~~~~~~~~~~~^^
File "/tmp/solution.py", line 64, in top_power
if self.sideA_coverage == 0:
^^^^^^^^^^^^^^^^^^^
AttributeError: 'Egg' object has no attribute 'sideA_coverage'
----------------------------------------------------------------------
Ran 46 tests in 0.003s
FAILED (errors=1)
16.04.2026 19:19
16.04.2026 19:22
16.04.2026 19:22
16.04.2026 19:26
16.04.2026 19:25
16.04.2026 19:26
16.04.2026 19:27
16.04.2026 19:28
16.04.2026 19:28
16.04.2026 19:30