1import re
2class Egg:
3 def __init__(self):
4 self.paints = []
5 self.total_percentage = 0.0
6 self.broken_top = False
7 self.broken_bottom = False
8 self.tournament = None
9
10
11 def paint(self, *args):
12 current_sum = sum(p for _, p in args)
13 if self.total_percentage + current_sum > 100.0:
14 raise ValueError("Egg filling exceeds 100%")
15
16 for hex_color, percentage in args:
17 self.paints.append((hex_color.upper(), percentage))
18 self.total_percentage += percentage
19
20
21 def _get_strength(self, side):
22 start_bound = 0.0 if side == 'top' else 50.0
23 end_bound = 50.0 if side == 'top' else 100.0
24 total_strength = 0.0
25 current_offset = 0.0
26 has_any_paint = False
27 for hex_color, percentage in self.paints:
28 color_start = current_offset
29 color_end = current_offset + percentage
30 overlap_start = max(color_start, start_bound)
31 overlap_end = min(color_end, end_bound)
32 if overlap_end > overlap_start:
33 has_any_paint = True
34 actual_p = overlap_end - overlap_start
35 r = int(hex_color[0:2], 16)
36 g = int(hex_color[2:4], 16)
37 b = int(hex_color[4:6], 16)
38 total_strength += (r + g + b) * (actual_p / 100.0)
39
40 current_offset += percentage
41 if has_any_paint and total_strength == 0:
42 return 1e-9
43 return total_strength
44
45
46 def _collide(self, other, side):
47 if not isinstance(other, Egg):
48 return NotImplemented
49 if side == 'top':
50 if self.broken_top: raise TypeError("Self egg top is broken")
51 if other.broken_top: raise TypeError("Other egg top is broken")
52 else:
53 if self.broken_bottom: raise TypeError("Self egg bottom is broken")
54 if other.broken_bottom: raise TypeError("Other egg bottom is broken")
55 s1 = self._get_strength(side)
56 s2 = other._get_strength(side)
57
58 winner = self if s1 > s2 else other
59 loser = other if s1 > s2 else self
60
61 if side == 'top':
62 loser.broken_top = True
63 else:
64 loser.broken_bottom = True
65
66 if self.tournament and other.tournament and self.tournament == other.tournament:
67 self.tournament._record_match(self, other, side, winner)
68
69 return winner
70
71
72 def __mul__(self, other):
73 return self._collide(other, 'top')
74
75 def __rmul__(self, other):
76 return self._collide(other, 'top')
77
78 def __matmul__(self, other):
79 return self._collide(other, 'bottom')
80
81 def __rmatmul__(self, other):
82 return self._collide(other, 'bottom')
83
84
85class EggTournament:
86 def __init__(self):
87 self.eggs = {}
88 self.egg_to_name = {}
89 self.matches = {}
90 self.wins = {}
91
92
93 def register(self, egg, name):
94 if not re.fullmatch(r'[a-zA-Z_][a-zA-Z0-9_]*', name):
95 raise ValueError("Invalid registration name")
96 if egg.tournament is not None:
97 raise ValueError("An egg cannot be registered in multiple tournaments")
98 if name in self.eggs:
99 raise ValueError(f"Egg with name {name} has already been registered")
100
101 egg.tournament = self
102 self.eggs[name] = egg
103 self.egg_to_name[egg] = name
104 self.wins[egg] = 0
105
106
107 def _record_match(self, egg1, egg2, side, winner):
108 self.matches[(frozenset({egg1, egg2}), side)] = winner
109 self.wins[winner] += 1
110
111
112 def __getitem__(self, key):
113 if isinstance(key, slice):
114 egg1, egg2, side = key.start, key.stop, key.step
115 else:
116 egg1, egg2, side = key
117
118 match_key = (frozenset({egg1, egg2}), side)
119 if match_key not in self.matches:
120 raise KeyError("Match not found")
121 return self.matches[match_key]
122
123
124 def _get_rankings(self):
125 sorted_eggs = sorted(self.wins.items(), key=lambda x: x[1], reverse=True)
126 ranks = {}
127 current_rank = 1
128 last_wins = -1
129
130 temp_ranks = []
131 for egg, win_count in sorted_eggs:
132 if win_count != last_wins:
133 if temp_ranks:
134 current_rank += 1
135 last_wins = win_count
136 temp_ranks.append((egg, current_rank))
137
138 final_ranks = {}
139 for egg, r in temp_ranks:
140 final_ranks.setdefault(r, set()).add(egg)
141 return final_ranks
142
143
144 def __rmatmul__(self, pos):
145 if not isinstance(pos, int):
146 return NotImplemented
147 rankings = self._get_rankings()
148 if pos not in rankings:
149 raise IndexError("Position not found in ranking")
150 res = rankings[pos]
151 return list(res)[0] if len(res) == 1 else res
152
153
154 def __getattr__(self, name):
155 if name in self.eggs:
156 egg = self.eggs[name]
157 rankings = self._get_rankings()
158 pos = next(r for r, eggs in rankings.items() if egg in eggs)
159 return {"position": pos, "victories": self.wins[egg]}
160 raise AttributeError("Apologies, there is no such egg registered")
161
162
163 def __contains__(self, egg):
164 return egg in self.egg_to_name
..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.002s
OK
17.04.2026 22:05
17.04.2026 22:07
17.04.2026 22:09
17.04.2026 22:07
17.04.2026 22:11
17.04.2026 22:11