1class Egg:
2 def __init__(self):
3 self.top_side_paints = list()
4 self.bottom_side_paints = list()
5 self.painted_percentage = 0.0
6 self.is_top_side_broken = False
7 self.is_bottom_side_broken = False
8 self._tournament = None
9
10 def paint(self, *args):
11 total = sum(paint[1] for paint in args)
12
13 if self.painted_percentage + total > 100.0:
14 raise ValueError
15
16 for color, percent in args:
17 if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0:
18 self.top_side_paints.append((color, percent))
19 self.painted_percentage += percent
20
21 elif self.painted_percentage >= 50.0:
22 self.bottom_side_paints.append((color, percent))
23 self.painted_percentage += percent
24
25 else:
26 remaining_top = 50.0 - self.painted_percentage
27 self.top_side_paints.append((color, remaining_top))
28 self.bottom_side_paints.append((color, percent - remaining_top))
29 self.painted_percentage += percent
30
31 @staticmethod
32 def strength(paints):
33 strength = 0
34 for paint, amount in paints:
35 strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100
36 return strength
37
38 def __mul__(self, other):
39 if not isinstance(other, Egg):
40 return NotImplemented
41 if self is other:
42 return NotImplemented
43 if self.is_top_side_broken or other.is_top_side_broken:
44 raise TypeError("Махай се от тука загубеняк")
45 if not self.top_side_paints:
46 self.is_top_side_broken = True
47 winner = other
48 elif not other.top_side_paints:
49 other.is_top_side_broken = True
50 winner = self
51 elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints):
52 other.is_top_side_broken = True
53 winner = self
54 else:
55 self.is_top_side_broken = True
56 winner = other
57 if self._tournament is not None and self._tournament is other._tournament:
58 self._tournament._record_battle(self, other, "top", winner)
59
60 return winner
61
62 def __matmul__(self, other):
63 if not isinstance(other, Egg):
64 return NotImplemented
65 if self is other:
66 return NotImplemented
67 if self.is_bottom_side_broken or other.is_bottom_side_broken:
68 raise TypeError("Махай се от тука загубеняк")
69 if not self.bottom_side_paints:
70 self.is_bottom_side_broken = True
71 winner = other
72 elif not other.bottom_side_paints:
73 other.is_bottom_side_broken = True
74 winner = self
75 elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints):
76 other.is_bottom_side_broken = True
77 winner = self
78 else:
79 self.is_bottom_side_broken = True
80 winner = other
81 if self._tournament is not None and self._tournament is other._tournament:
82 self._tournament._record_battle(self, other, "bottom", winner)
83
84 return winner
85
86
87class EggTournament:
88 def __init__(self):
89 self.history = dict()
90 self.eggs = dict()
91 self.names = dict()
92 self.victories = dict()
93
94
95
96 def _record_battle(self, egg1, egg2, side, winner):
97 key = (frozenset((egg1, egg2)), side)
98 self.history[key] = winner
99 self.victories[winner] += 1
100
101 def register(self, egg, name):
102 if egg._tournament is not None:
103 raise ValueError("An egg cannot be registered in multiple tournaments")
104
105 if not name.isidentifier():
106 raise ValueError("Invalid registration name")
107
108 if name in self.names:
109 raise ValueError(f"Egg with name {name} has already been registered")
110
111 egg._tournament = self
112 self.names[name] = egg
113 self.eggs[egg] = name
114 self.victories[egg] = 0
115
116 def __getitem__(self, key):
117 if isinstance(key, tuple):
118 if len(key) != 3:
119 raise KeyError("Wrong access")
120 else:
121 egg1 = key[0]
122 egg2 = key[1]
123 side = key[2]
124 elif isinstance(key, slice):
125 egg1 = key.start
126 egg2 = key.stop
127 side = key.step
128 else:
129 raise KeyError("Wrong access")
130
131 if side not in ("top", "bottom"):
132 raise KeyError("Wrong access")
133
134 lookup_key = (frozenset((egg1, egg2)), side)
135
136 if lookup_key not in self.history:
137 raise KeyError("No such battle recorded")
138
139 return self.history[lookup_key]
140
141 def get_ranking(self):
142 sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True)
143 ranking = {}
144 current_rank = 0
145 last_victory_count = None
146
147 for egg, victory_count in sorted_victories:
148 if victory_count != last_victory_count:
149 current_rank += 1
150 last_victory_count = victory_count
151 ranking[egg] = current_rank
152
153 return ranking
154
155 def __rmatmul__(self, index):
156 if not isinstance(index, int):
157 return NotImplemented
158 ranking = self.get_ranking()
159
160 eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index}
161 if not eggs_at_rank:
162 raise IndexError("No eggs at this rank")
163
164 if len(eggs_at_rank) == 1:
165 return eggs_at_rank.pop()
166
167 return eggs_at_rank
168
169 def __getattr__(self, name):
170 if name not in self.names:
171 raise AttributeError("Apologies, there is no such egg registered")
172
173 egg = self.names[name]
174 ranking = self.get_ranking()
175
176 return {"position": ranking[egg], "victories": self.victories[egg]}
177
178 def __contains__(self, egg):
179 return egg in self.eggs
180
181
182
183
184
185
186
187
188
189
190# my_egg = Egg()
191# my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0))
192
193# your_egg = Egg()
194# your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0))
195
196# print(my_egg)
197# print(your_egg)
198
199
200# #my_egg = Egg()
201# #your_egg = Egg()
202# tournament = EggTournament()
203
204# tournament.register(my_egg, "the_monster")
205# tournament.register(your_egg, "the_pink_princess123")
206
207# print(my_egg * your_egg)
208# print(my_egg @ your_egg)
209
210# print(tournament[your_egg, my_egg, "bottom"])
211# print(tournament[my_egg, your_egg, "bottom"])
212# print(tournament.the_monster)
213# print(tournament.the_pink_princess123)
214# print(1 @ tournament)
..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.001s
OK
| f | 1 | f | 1 | ||
| 2 | class Egg: | 2 | class Egg: | ||
| 3 | def __init__(self): | 3 | def __init__(self): | ||
| 4 | self.top_side_paints = list() | 4 | self.top_side_paints = list() | ||
| 5 | self.bottom_side_paints = list() | 5 | self.bottom_side_paints = list() | ||
| 6 | self.painted_percentage = 0.0 | 6 | self.painted_percentage = 0.0 | ||
| 7 | self.is_top_side_broken = False | 7 | self.is_top_side_broken = False | ||
| 8 | self.is_bottom_side_broken = False | 8 | self.is_bottom_side_broken = False | ||
| 9 | self._tournament = None | 9 | self._tournament = None | ||
| 10 | 10 | ||||
| 11 | def paint(self, *args): | 11 | def paint(self, *args): | ||
| 12 | total = sum(paint[1] for paint in args) | 12 | total = sum(paint[1] for paint in args) | ||
| 13 | 13 | ||||
| 14 | if self.painted_percentage + total > 100.0: | 14 | if self.painted_percentage + total > 100.0: | ||
| 15 | raise ValueError | 15 | raise ValueError | ||
| 16 | 16 | ||||
| 17 | for color, percent in args: | 17 | for color, percent in args: | ||
| 18 | if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0: | 18 | if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0: | ||
| 19 | self.top_side_paints.append((color, percent)) | 19 | self.top_side_paints.append((color, percent)) | ||
| 20 | self.painted_percentage += percent | 20 | self.painted_percentage += percent | ||
| 21 | 21 | ||||
| 22 | elif self.painted_percentage >= 50.0: | 22 | elif self.painted_percentage >= 50.0: | ||
| 23 | self.bottom_side_paints.append((color, percent)) | 23 | self.bottom_side_paints.append((color, percent)) | ||
| 24 | self.painted_percentage += percent | 24 | self.painted_percentage += percent | ||
| 25 | 25 | ||||
| 26 | else: | 26 | else: | ||
| 27 | remaining_top = 50.0 - self.painted_percentage | 27 | remaining_top = 50.0 - self.painted_percentage | ||
| 28 | self.top_side_paints.append((color, remaining_top)) | 28 | self.top_side_paints.append((color, remaining_top)) | ||
| 29 | self.bottom_side_paints.append((color, percent - remaining_top)) | 29 | self.bottom_side_paints.append((color, percent - remaining_top)) | ||
| 30 | self.painted_percentage += percent | 30 | self.painted_percentage += percent | ||
| 31 | 31 | ||||
| 32 | @staticmethod | 32 | @staticmethod | ||
| 33 | def strength(paints): | 33 | def strength(paints): | ||
| 34 | strength = 0 | 34 | strength = 0 | ||
| 35 | for paint, amount in paints: | 35 | for paint, amount in paints: | ||
| 36 | strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100 | 36 | strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100 | ||
| 37 | return strength | 37 | return strength | ||
| 38 | 38 | ||||
| 39 | def __mul__(self, other): | 39 | def __mul__(self, other): | ||
| 40 | if not isinstance(other, Egg): | 40 | if not isinstance(other, Egg): | ||
| 41 | return NotImplemented | 41 | return NotImplemented | ||
| 42 | if self is other: | 42 | if self is other: | ||
| 43 | return NotImplemented | 43 | return NotImplemented | ||
| 44 | if self.is_top_side_broken or other.is_top_side_broken: | 44 | if self.is_top_side_broken or other.is_top_side_broken: | ||
| 45 | raise TypeError("Махай се от тука загубеняк") | 45 | raise TypeError("Махай се от тука загубеняк") | ||
| 46 | if not self.top_side_paints: | 46 | if not self.top_side_paints: | ||
| 47 | self.is_top_side_broken = True | 47 | self.is_top_side_broken = True | ||
| 48 | winner = other | 48 | winner = other | ||
| 49 | elif not other.top_side_paints: | 49 | elif not other.top_side_paints: | ||
| 50 | other.is_top_side_broken = True | 50 | other.is_top_side_broken = True | ||
| 51 | winner = self | 51 | winner = self | ||
| 52 | elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints): | 52 | elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints): | ||
| 53 | other.is_top_side_broken = True | 53 | other.is_top_side_broken = True | ||
| 54 | winner = self | 54 | winner = self | ||
| 55 | else: | 55 | else: | ||
| 56 | self.is_top_side_broken = True | 56 | self.is_top_side_broken = True | ||
| 57 | winner = other | 57 | winner = other | ||
| 58 | if self._tournament is not None and self._tournament is other._tournament: | 58 | if self._tournament is not None and self._tournament is other._tournament: | ||
| 59 | self._tournament._record_battle(self, other, "top", winner) | 59 | self._tournament._record_battle(self, other, "top", winner) | ||
| 60 | 60 | ||||
| 61 | return winner | 61 | return winner | ||
| 62 | 62 | ||||
| 63 | def __matmul__(self, other): | 63 | def __matmul__(self, other): | ||
| 64 | if not isinstance(other, Egg): | 64 | if not isinstance(other, Egg): | ||
| 65 | return NotImplemented | 65 | return NotImplemented | ||
| 66 | if self is other: | 66 | if self is other: | ||
| 67 | return NotImplemented | 67 | return NotImplemented | ||
| 68 | if self.is_bottom_side_broken or other.is_bottom_side_broken: | 68 | if self.is_bottom_side_broken or other.is_bottom_side_broken: | ||
| 69 | raise TypeError("Махай се от тука загубеняк") | 69 | raise TypeError("Махай се от тука загубеняк") | ||
| 70 | if not self.bottom_side_paints: | 70 | if not self.bottom_side_paints: | ||
| 71 | self.is_bottom_side_broken = True | 71 | self.is_bottom_side_broken = True | ||
| 72 | winner = other | 72 | winner = other | ||
| 73 | elif not other.bottom_side_paints: | 73 | elif not other.bottom_side_paints: | ||
| 74 | other.is_bottom_side_broken = True | 74 | other.is_bottom_side_broken = True | ||
| 75 | winner = self | 75 | winner = self | ||
| 76 | elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints): | 76 | elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints): | ||
| 77 | other.is_bottom_side_broken = True | 77 | other.is_bottom_side_broken = True | ||
| 78 | winner = self | 78 | winner = self | ||
| 79 | else: | 79 | else: | ||
| 80 | self.is_bottom_side_broken = True | 80 | self.is_bottom_side_broken = True | ||
| 81 | winner = other | 81 | winner = other | ||
| 82 | if self._tournament is not None and self._tournament is other._tournament: | 82 | if self._tournament is not None and self._tournament is other._tournament: | ||
| 83 | self._tournament._record_battle(self, other, "bottom", winner) | 83 | self._tournament._record_battle(self, other, "bottom", winner) | ||
| 84 | 84 | ||||
| 85 | return winner | 85 | return winner | ||
| 86 | 86 | ||||
| 87 | 87 | ||||
| 88 | class EggTournament: | 88 | class EggTournament: | ||
| 89 | def __init__(self): | 89 | def __init__(self): | ||
| 90 | self.history = dict() | 90 | self.history = dict() | ||
| 91 | self.eggs = dict() | 91 | self.eggs = dict() | ||
| 92 | self.names = dict() | 92 | self.names = dict() | ||
| 93 | self.victories = dict() | 93 | self.victories = dict() | ||
| 94 | 94 | ||||
| 95 | 95 | ||||
| 96 | 96 | ||||
| 97 | def _record_battle(self, egg1, egg2, side, winner): | 97 | def _record_battle(self, egg1, egg2, side, winner): | ||
| 98 | key = (frozenset((egg1, egg2)), side) | 98 | key = (frozenset((egg1, egg2)), side) | ||
| 99 | self.history[key] = winner | 99 | self.history[key] = winner | ||
| 100 | self.victories[winner] += 1 | 100 | self.victories[winner] += 1 | ||
| 101 | 101 | ||||
| 102 | def register(self, egg, name): | 102 | def register(self, egg, name): | ||
| 103 | if egg._tournament is not None: | 103 | if egg._tournament is not None: | ||
| 104 | raise ValueError("An egg cannot be registered in multiple tournaments") | 104 | raise ValueError("An egg cannot be registered in multiple tournaments") | ||
| 105 | 105 | ||||
| 106 | if not name.isidentifier(): | 106 | if not name.isidentifier(): | ||
| 107 | raise ValueError("Invalid registration name") | 107 | raise ValueError("Invalid registration name") | ||
| 108 | 108 | ||||
| 109 | if name in self.names: | 109 | if name in self.names: | ||
| 110 | raise ValueError(f"Egg with name {name} has already been registered") | 110 | raise ValueError(f"Egg with name {name} has already been registered") | ||
| 111 | 111 | ||||
| 112 | egg._tournament = self | 112 | egg._tournament = self | ||
| 113 | self.names[name] = egg | 113 | self.names[name] = egg | ||
| 114 | self.eggs[egg] = name | 114 | self.eggs[egg] = name | ||
| 115 | self.victories[egg] = 0 | 115 | self.victories[egg] = 0 | ||
| 116 | 116 | ||||
| 117 | def __getitem__(self, key): | 117 | def __getitem__(self, key): | ||
| 118 | if isinstance(key, tuple): | 118 | if isinstance(key, tuple): | ||
| 119 | if len(key) != 3: | 119 | if len(key) != 3: | ||
| 120 | raise KeyError("Wrong access") | 120 | raise KeyError("Wrong access") | ||
| 121 | else: | 121 | else: | ||
| 122 | egg1 = key[0] | 122 | egg1 = key[0] | ||
| 123 | egg2 = key[1] | 123 | egg2 = key[1] | ||
| 124 | side = key[2] | 124 | side = key[2] | ||
| 125 | elif isinstance(key, slice): | 125 | elif isinstance(key, slice): | ||
| 126 | egg1 = key.start | 126 | egg1 = key.start | ||
| 127 | egg2 = key.stop | 127 | egg2 = key.stop | ||
| 128 | side = key.step | 128 | side = key.step | ||
| 129 | else: | 129 | else: | ||
| 130 | raise KeyError("Wrong access") | 130 | raise KeyError("Wrong access") | ||
| 131 | 131 | ||||
| 132 | if side not in ("top", "bottom"): | 132 | if side not in ("top", "bottom"): | ||
| 133 | raise KeyError("Wrong access") | 133 | raise KeyError("Wrong access") | ||
| 134 | 134 | ||||
| 135 | lookup_key = (frozenset((egg1, egg2)), side) | 135 | lookup_key = (frozenset((egg1, egg2)), side) | ||
| 136 | 136 | ||||
| 137 | if lookup_key not in self.history: | 137 | if lookup_key not in self.history: | ||
| 138 | raise KeyError("No such battle recorded") | 138 | raise KeyError("No such battle recorded") | ||
| 139 | 139 | ||||
| 140 | return self.history[lookup_key] | 140 | return self.history[lookup_key] | ||
| 141 | 141 | ||||
| 142 | def get_ranking(self): | 142 | def get_ranking(self): | ||
| 143 | sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True) | 143 | sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True) | ||
| 144 | ranking = {} | 144 | ranking = {} | ||
| 145 | current_rank = 0 | 145 | current_rank = 0 | ||
| 146 | last_victory_count = None | 146 | last_victory_count = None | ||
| 147 | 147 | ||||
| 148 | for egg, victory_count in sorted_victories: | 148 | for egg, victory_count in sorted_victories: | ||
| 149 | if victory_count != last_victory_count: | 149 | if victory_count != last_victory_count: | ||
| 150 | current_rank += 1 | 150 | current_rank += 1 | ||
| 151 | last_victory_count = victory_count | 151 | last_victory_count = victory_count | ||
| 152 | ranking[egg] = current_rank | 152 | ranking[egg] = current_rank | ||
| 153 | 153 | ||||
| 154 | return ranking | 154 | return ranking | ||
| 155 | 155 | ||||
| 156 | def __rmatmul__(self, index): | 156 | def __rmatmul__(self, index): | ||
| 157 | if not isinstance(index, int): | 157 | if not isinstance(index, int): | ||
| 158 | return NotImplemented | 158 | return NotImplemented | ||
| 159 | ranking = self.get_ranking() | 159 | ranking = self.get_ranking() | ||
| 160 | 160 | ||||
| 161 | eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index} | 161 | eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index} | ||
| 162 | if not eggs_at_rank: | 162 | if not eggs_at_rank: | ||
| 163 | raise IndexError("No eggs at this rank") | 163 | raise IndexError("No eggs at this rank") | ||
| 164 | 164 | ||||
| 165 | if len(eggs_at_rank) == 1: | 165 | if len(eggs_at_rank) == 1: | ||
| 166 | return eggs_at_rank.pop() | 166 | return eggs_at_rank.pop() | ||
| 167 | 167 | ||||
| 168 | return eggs_at_rank | 168 | return eggs_at_rank | ||
| 169 | 169 | ||||
| 170 | def __getattr__(self, name): | 170 | def __getattr__(self, name): | ||
| 171 | if name not in self.names: | 171 | if name not in self.names: | ||
| 172 | raise AttributeError("Apologies, there is no such egg registered") | 172 | raise AttributeError("Apologies, there is no such egg registered") | ||
| 173 | 173 | ||||
| 174 | egg = self.names[name] | 174 | egg = self.names[name] | ||
| 175 | ranking = self.get_ranking() | 175 | ranking = self.get_ranking() | ||
| 176 | 176 | ||||
| 177 | return {"position": ranking[egg], "victories": self.victories[egg]} | 177 | return {"position": ranking[egg], "victories": self.victories[egg]} | ||
| 178 | 178 | ||||
| 179 | def __contains__(self, egg): | 179 | def __contains__(self, egg): | ||
| 180 | return egg in self.eggs | 180 | return egg in self.eggs | ||
| 181 | 181 | ||||
| 182 | 182 | ||||
| 183 | 183 | ||||
| 184 | 184 | ||||
| 185 | 185 | ||||
| 186 | 186 | ||||
| 187 | 187 | ||||
| 188 | 188 | ||||
| 189 | 189 | ||||
| 190 | 190 | ||||
| n | 191 | my_egg = Egg() | n | ||
| 192 | my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0)) | ||||
| 193 | |||||
| 194 | your_egg = Egg() | ||||
| 195 | your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0)) | ||||
| 196 | |||||
| 197 | print(my_egg) | ||||
| 198 | print(your_egg) | ||||
| 199 | |||||
| 200 | |||||
| 201 | #my_egg = Egg() | 191 | # my_egg = Egg() | ||
| 192 | # my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0)) | ||||
| 193 | |||||
| 202 | #your_egg = Egg() | 194 | # your_egg = Egg() | ||
| 203 | tournament = EggTournament() | 195 | # your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0)) | ||
| 204 | 196 | ||||
| n | 205 | tournament.register(my_egg, "the_monster") | n | 197 | # print(my_egg) |
| 206 | tournament.register(your_egg, "the_pink_princess123") | 198 | # print(your_egg) | ||
| 207 | 199 | ||||
| n | 208 | print(my_egg * your_egg) | n | ||
| 209 | print(my_egg @ your_egg) | ||||
| 210 | 200 | ||||
| t | t | 201 | # #my_egg = Egg() | ||
| 202 | # #your_egg = Egg() | ||||
| 203 | # tournament = EggTournament() | ||||
| 204 | |||||
| 205 | # tournament.register(my_egg, "the_monster") | ||||
| 206 | # tournament.register(your_egg, "the_pink_princess123") | ||||
| 207 | |||||
| 208 | # print(my_egg * your_egg) | ||||
| 209 | # print(my_egg @ your_egg) | ||||
| 210 | |||||
| 211 | print(tournament[your_egg, my_egg, "bottom"]) | 211 | # print(tournament[your_egg, my_egg, "bottom"]) | ||
| 212 | print(tournament[my_egg, your_egg, "bottom"]) | 212 | # print(tournament[my_egg, your_egg, "bottom"]) | ||
| 213 | print(tournament.the_monster) | 213 | # print(tournament.the_monster) | ||
| 214 | print(tournament.the_pink_princess123) | 214 | # print(tournament.the_pink_princess123) | ||
| 215 | print(1 @ tournament) | 215 | # print(1 @ tournament) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | f | 1 | ||
| 2 | class Egg: | 2 | class Egg: | ||
| 3 | def __init__(self): | 3 | def __init__(self): | ||
| 4 | self.top_side_paints = list() | 4 | self.top_side_paints = list() | ||
| 5 | self.bottom_side_paints = list() | 5 | self.bottom_side_paints = list() | ||
| 6 | self.painted_percentage = 0.0 | 6 | self.painted_percentage = 0.0 | ||
| 7 | self.is_top_side_broken = False | 7 | self.is_top_side_broken = False | ||
| 8 | self.is_bottom_side_broken = False | 8 | self.is_bottom_side_broken = False | ||
| 9 | self._tournament = None | 9 | self._tournament = None | ||
| 10 | 10 | ||||
| n | 11 | n | |||
| 12 | def paint(self, *args): | 11 | def paint(self, *args): | ||
| n | 13 | for paint in args: | n | 12 | total = sum(paint[1] for paint in args) |
| 14 | if self.painted_percentage < 50.0 and paint[1] + self.painted_percentage <= 50.0: | 13 | |||
| 15 | self.top_side_paints.append(paint) | ||||
| 16 | self.painted_percentage += paint[1] | ||||
| 17 | elif self.painted_percentage >= 50.0 and paint[1] + self.painted_percentage <= 100.0: | ||||
| 18 | self.bottom_side_paints.append(paint) | ||||
| 19 | self.painted_percentage += paint[1] | ||||
| 20 | elif self.painted_percentage < 50.0 and paint[1] + self.painted_percentage > 50.0 and paint[1] + self.painted_percentage <= 100.0: | ||||
| 21 | remaining_top_paint = 50.0 - self.painted_percentage | ||||
| 22 | self.top_side_paints.append((paint[0], remaining_top_paint)) | ||||
| 23 | self.bottom_side_paints.append((paint[0], paint[1] - remaining_top_paint)) | ||||
| 24 | self.painted_percentage += paint[1] | ||||
| 25 | elif self.painted_percentage + paint[1] > 100.0: | 14 | if self.painted_percentage + total > 100.0: | ||
| 26 | raise ValueError | 15 | raise ValueError | ||
| 16 | |||||
| 17 | for color, percent in args: | ||||
| 18 | if self.painted_percentage < 50.0 and self.painted_percentage + percent <= 50.0: | ||||
| 19 | self.top_side_paints.append((color, percent)) | ||||
| 20 | self.painted_percentage += percent | ||||
| 21 | |||||
| 22 | elif self.painted_percentage >= 50.0: | ||||
| 23 | self.bottom_side_paints.append((color, percent)) | ||||
| 24 | self.painted_percentage += percent | ||||
| 25 | |||||
| 26 | else: | ||||
| 27 | remaining_top = 50.0 - self.painted_percentage | ||||
| 28 | self.top_side_paints.append((color, remaining_top)) | ||||
| 29 | self.bottom_side_paints.append((color, percent - remaining_top)) | ||||
| 30 | self.painted_percentage += percent | ||||
| 27 | 31 | ||||
| 28 | @staticmethod | 32 | @staticmethod | ||
| 29 | def strength(paints): | 33 | def strength(paints): | ||
| 30 | strength = 0 | 34 | strength = 0 | ||
| 31 | for paint, amount in paints: | 35 | for paint, amount in paints: | ||
| 32 | strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100 | 36 | strength += (int(paint[0:2], 16) + int(paint[2:4], 16) + int(paint[4:6], 16)) * amount * 2 / 100 | ||
| 33 | return strength | 37 | return strength | ||
| 34 | 38 | ||||
| 35 | def __mul__(self, other): | 39 | def __mul__(self, other): | ||
| 36 | if not isinstance(other, Egg): | 40 | if not isinstance(other, Egg): | ||
| 37 | return NotImplemented | 41 | return NotImplemented | ||
| 38 | if self is other: | 42 | if self is other: | ||
| 39 | return NotImplemented | 43 | return NotImplemented | ||
| 40 | if self.is_top_side_broken or other.is_top_side_broken: | 44 | if self.is_top_side_broken or other.is_top_side_broken: | ||
| 41 | raise TypeError("Махай се от тука загубеняк") | 45 | raise TypeError("Махай се от тука загубеняк") | ||
| 42 | if not self.top_side_paints: | 46 | if not self.top_side_paints: | ||
| 43 | self.is_top_side_broken = True | 47 | self.is_top_side_broken = True | ||
| 44 | winner = other | 48 | winner = other | ||
| 45 | elif not other.top_side_paints: | 49 | elif not other.top_side_paints: | ||
| 46 | other.is_top_side_broken = True | 50 | other.is_top_side_broken = True | ||
| 47 | winner = self | 51 | winner = self | ||
| 48 | elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints): | 52 | elif Egg.strength(self.top_side_paints) > Egg.strength(other.top_side_paints): | ||
| 49 | other.is_top_side_broken = True | 53 | other.is_top_side_broken = True | ||
| 50 | winner = self | 54 | winner = self | ||
| 51 | else: | 55 | else: | ||
| 52 | self.is_top_side_broken = True | 56 | self.is_top_side_broken = True | ||
| 53 | winner = other | 57 | winner = other | ||
| 54 | if self._tournament is not None and self._tournament is other._tournament: | 58 | if self._tournament is not None and self._tournament is other._tournament: | ||
| 55 | self._tournament._record_battle(self, other, "top", winner) | 59 | self._tournament._record_battle(self, other, "top", winner) | ||
| 56 | 60 | ||||
| 57 | return winner | 61 | return winner | ||
| 58 | 62 | ||||
| 59 | def __matmul__(self, other): | 63 | def __matmul__(self, other): | ||
| 60 | if not isinstance(other, Egg): | 64 | if not isinstance(other, Egg): | ||
| 61 | return NotImplemented | 65 | return NotImplemented | ||
| 62 | if self is other: | 66 | if self is other: | ||
| 63 | return NotImplemented | 67 | return NotImplemented | ||
| 64 | if self.is_bottom_side_broken or other.is_bottom_side_broken: | 68 | if self.is_bottom_side_broken or other.is_bottom_side_broken: | ||
| 65 | raise TypeError("Махай се от тука загубеняк") | 69 | raise TypeError("Махай се от тука загубеняк") | ||
| 66 | if not self.bottom_side_paints: | 70 | if not self.bottom_side_paints: | ||
| 67 | self.is_bottom_side_broken = True | 71 | self.is_bottom_side_broken = True | ||
| 68 | winner = other | 72 | winner = other | ||
| 69 | elif not other.bottom_side_paints: | 73 | elif not other.bottom_side_paints: | ||
| 70 | other.is_bottom_side_broken = True | 74 | other.is_bottom_side_broken = True | ||
| 71 | winner = self | 75 | winner = self | ||
| 72 | elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints): | 76 | elif Egg.strength(self.bottom_side_paints) > Egg.strength(other.bottom_side_paints): | ||
| 73 | other.is_bottom_side_broken = True | 77 | other.is_bottom_side_broken = True | ||
| 74 | winner = self | 78 | winner = self | ||
| 75 | else: | 79 | else: | ||
| 76 | self.is_bottom_side_broken = True | 80 | self.is_bottom_side_broken = True | ||
| 77 | winner = other | 81 | winner = other | ||
| 78 | if self._tournament is not None and self._tournament is other._tournament: | 82 | if self._tournament is not None and self._tournament is other._tournament: | ||
| 79 | self._tournament._record_battle(self, other, "bottom", winner) | 83 | self._tournament._record_battle(self, other, "bottom", winner) | ||
| 80 | 84 | ||||
| 81 | return winner | 85 | return winner | ||
| 82 | 86 | ||||
| 83 | 87 | ||||
| 84 | class EggTournament: | 88 | class EggTournament: | ||
| 85 | def __init__(self): | 89 | def __init__(self): | ||
| 86 | self.history = dict() | 90 | self.history = dict() | ||
| 87 | self.eggs = dict() | 91 | self.eggs = dict() | ||
| 88 | self.names = dict() | 92 | self.names = dict() | ||
| 89 | self.victories = dict() | 93 | self.victories = dict() | ||
| 90 | 94 | ||||
| 91 | 95 | ||||
| 92 | 96 | ||||
| 93 | def _record_battle(self, egg1, egg2, side, winner): | 97 | def _record_battle(self, egg1, egg2, side, winner): | ||
| 94 | key = (frozenset((egg1, egg2)), side) | 98 | key = (frozenset((egg1, egg2)), side) | ||
| 95 | self.history[key] = winner | 99 | self.history[key] = winner | ||
| 96 | self.victories[winner] += 1 | 100 | self.victories[winner] += 1 | ||
| 97 | 101 | ||||
| 98 | def register(self, egg, name): | 102 | def register(self, egg, name): | ||
| 99 | if egg._tournament is not None: | 103 | if egg._tournament is not None: | ||
| 100 | raise ValueError("An egg cannot be registered in multiple tournaments") | 104 | raise ValueError("An egg cannot be registered in multiple tournaments") | ||
| 101 | 105 | ||||
| 102 | if not name.isidentifier(): | 106 | if not name.isidentifier(): | ||
| 103 | raise ValueError("Invalid registration name") | 107 | raise ValueError("Invalid registration name") | ||
| 104 | 108 | ||||
| 105 | if name in self.names: | 109 | if name in self.names: | ||
| 106 | raise ValueError(f"Egg with name {name} has already been registered") | 110 | raise ValueError(f"Egg with name {name} has already been registered") | ||
| 107 | 111 | ||||
| 108 | egg._tournament = self | 112 | egg._tournament = self | ||
| 109 | self.names[name] = egg | 113 | self.names[name] = egg | ||
| 110 | self.eggs[egg] = name | 114 | self.eggs[egg] = name | ||
| 111 | self.victories[egg] = 0 | 115 | self.victories[egg] = 0 | ||
| 112 | 116 | ||||
| 113 | def __getitem__(self, key): | 117 | def __getitem__(self, key): | ||
| 114 | if isinstance(key, tuple): | 118 | if isinstance(key, tuple): | ||
| 115 | if len(key) != 3: | 119 | if len(key) != 3: | ||
| 116 | raise KeyError("Wrong access") | 120 | raise KeyError("Wrong access") | ||
| 117 | else: | 121 | else: | ||
| 118 | egg1 = key[0] | 122 | egg1 = key[0] | ||
| 119 | egg2 = key[1] | 123 | egg2 = key[1] | ||
| 120 | side = key[2] | 124 | side = key[2] | ||
| 121 | elif isinstance(key, slice): | 125 | elif isinstance(key, slice): | ||
| 122 | egg1 = key.start | 126 | egg1 = key.start | ||
| 123 | egg2 = key.stop | 127 | egg2 = key.stop | ||
| 124 | side = key.step | 128 | side = key.step | ||
| 125 | else: | 129 | else: | ||
| 126 | raise KeyError("Wrong access") | 130 | raise KeyError("Wrong access") | ||
| 127 | 131 | ||||
| 128 | if side not in ("top", "bottom"): | 132 | if side not in ("top", "bottom"): | ||
| 129 | raise KeyError("Wrong access") | 133 | raise KeyError("Wrong access") | ||
| 130 | 134 | ||||
| 131 | lookup_key = (frozenset((egg1, egg2)), side) | 135 | lookup_key = (frozenset((egg1, egg2)), side) | ||
| 132 | 136 | ||||
| 133 | if lookup_key not in self.history: | 137 | if lookup_key not in self.history: | ||
| 134 | raise KeyError("No such battle recorded") | 138 | raise KeyError("No such battle recorded") | ||
| 135 | 139 | ||||
| 136 | return self.history[lookup_key] | 140 | return self.history[lookup_key] | ||
| 137 | 141 | ||||
| 138 | def get_ranking(self): | 142 | def get_ranking(self): | ||
| 139 | sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True) | 143 | sorted_victories = sorted(self.victories.items(), key=lambda item: item[1], reverse=True) | ||
| 140 | ranking = {} | 144 | ranking = {} | ||
| 141 | current_rank = 0 | 145 | current_rank = 0 | ||
| 142 | last_victory_count = None | 146 | last_victory_count = None | ||
| 143 | 147 | ||||
| 144 | for egg, victory_count in sorted_victories: | 148 | for egg, victory_count in sorted_victories: | ||
| 145 | if victory_count != last_victory_count: | 149 | if victory_count != last_victory_count: | ||
| 146 | current_rank += 1 | 150 | current_rank += 1 | ||
| 147 | last_victory_count = victory_count | 151 | last_victory_count = victory_count | ||
| 148 | ranking[egg] = current_rank | 152 | ranking[egg] = current_rank | ||
| 149 | 153 | ||||
| 150 | return ranking | 154 | return ranking | ||
| 151 | 155 | ||||
| 152 | def __rmatmul__(self, index): | 156 | def __rmatmul__(self, index): | ||
| 153 | if not isinstance(index, int): | 157 | if not isinstance(index, int): | ||
| 154 | return NotImplemented | 158 | return NotImplemented | ||
| 155 | ranking = self.get_ranking() | 159 | ranking = self.get_ranking() | ||
| 156 | 160 | ||||
| 157 | eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index} | 161 | eggs_at_rank = {egg for egg, rank in ranking.items() if rank == index} | ||
| 158 | if not eggs_at_rank: | 162 | if not eggs_at_rank: | ||
| 159 | raise IndexError("No eggs at this rank") | 163 | raise IndexError("No eggs at this rank") | ||
| 160 | 164 | ||||
| 161 | if len(eggs_at_rank) == 1: | 165 | if len(eggs_at_rank) == 1: | ||
| 162 | return eggs_at_rank.pop() | 166 | return eggs_at_rank.pop() | ||
| 163 | 167 | ||||
| 164 | return eggs_at_rank | 168 | return eggs_at_rank | ||
| 165 | 169 | ||||
| 166 | def __getattr__(self, name): | 170 | def __getattr__(self, name): | ||
| 167 | if name not in self.names: | 171 | if name not in self.names: | ||
| 168 | raise AttributeError("Apologies, there is no such egg registered") | 172 | raise AttributeError("Apologies, there is no such egg registered") | ||
| 169 | 173 | ||||
| 170 | egg = self.names[name] | 174 | egg = self.names[name] | ||
| 171 | ranking = self.get_ranking() | 175 | ranking = self.get_ranking() | ||
| 172 | 176 | ||||
| 173 | return {"position": ranking[egg], "victories": self.victories[egg]} | 177 | return {"position": ranking[egg], "victories": self.victories[egg]} | ||
| 174 | 178 | ||||
| 175 | def __contains__(self, egg): | 179 | def __contains__(self, egg): | ||
| 176 | return egg in self.eggs | 180 | return egg in self.eggs | ||
| 177 | 181 | ||||
| 178 | 182 | ||||
| 179 | 183 | ||||
| 180 | 184 | ||||
| 181 | 185 | ||||
| 182 | 186 | ||||
| 183 | 187 | ||||
| 184 | 188 | ||||
| 185 | 189 | ||||
| 186 | 190 | ||||
| n | 187 | # my_egg = Egg() | n | 191 | my_egg = Egg() |
| 188 | # my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0)) | 192 | my_egg.paint(("AA2C00", 50.0), ("FFFF00", 50.0)) | ||
| 189 | 193 | ||||
| n | 190 | # your_egg = Egg() | n | 194 | your_egg = Egg() |
| 191 | # your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0)) | 195 | your_egg.paint(("0000FF", 25.0), ("DD0000", 25.0), ("FFFE00", 50.0)) | ||
| 192 | 196 | ||||
| n | 193 | # print(my_egg) | n | 197 | print(my_egg) |
| 194 | # print(your_egg) | 198 | print(your_egg) | ||
| 195 | 199 | ||||
| 196 | 200 | ||||
| n | 197 | # #my_egg = Egg() | n | 201 | #my_egg = Egg() |
| 198 | # #your_egg = Egg() | 202 | #your_egg = Egg() | ||
| 199 | # tournament = EggTournament() | 203 | tournament = EggTournament() | ||
| 200 | 204 | ||||
| n | 201 | # tournament.register(my_egg, "the_monster") | n | 205 | tournament.register(my_egg, "the_monster") |
| 202 | # tournament.register(your_egg, "the_pink_princess123") | 206 | tournament.register(your_egg, "the_pink_princess123") | ||
| 203 | 207 | ||||
| n | 204 | # print(my_egg * your_egg) | n | 208 | print(my_egg * your_egg) |
| 205 | # print(my_egg @ your_egg) | 209 | print(my_egg @ your_egg) | ||
| 206 | 210 | ||||
| t | 207 | # print(tournament[your_egg, my_egg, "bottom"]) | t | 211 | print(tournament[your_egg, my_egg, "bottom"]) |
| 208 | # print(tournament[my_egg, your_egg, "bottom"]) | 212 | print(tournament[my_egg, your_egg, "bottom"]) | ||
| 209 | # print(tournament.the_monster) | 213 | print(tournament.the_monster) | ||
| 210 | # print(tournament.the_pink_princess123) | 214 | print(tournament.the_pink_princess123) | ||
| 211 | # print(1 @ tournament) | 215 | print(1 @ tournament) |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
15.04.2026 16:44
15.04.2026 16:46
15.04.2026 16:48
15.04.2026 16:50
15.04.2026 16:51
15.04.2026 16:51
15.04.2026 16:52