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

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

6 точки общо

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

  1from collections import defaultdict
  2import keyword
  3
  4class Egg:
  5
  6    def __init__(self):
  7        self._percentage_painted = 0.0
  8        self._top_broken = False
  9        self._bottom_broken = False
 10        self._color = []
 11        self.tournament = None
 12
 13    def paint(self, *args):
 14         
 15     total = sum(percentage for _, percentage in args)
 16     if round(total + self.percentage_painted, 5) > 100.0:
 17            raise ValueError("Total percentage cannot exceed 100%")
 18   
 19     for hex_color, percentage in args:
 20        color = hex_color.upper()
 21
 22        start = self._percentage_painted
 23        end = self._percentage_painted + percentage
 24
 25        if start < 50.0 and end > 50.0:
 26            self._color.append((color, 50.0 - start))
 27            self._color.append((color, end - 50.0))
 28        else:
 29            self._color.append((color, percentage))
 30
 31        self._percentage_painted += percentage
 32
 33    def calculate_color_strength(self, color):
 34        r = int(color[0:2], 16)
 35        g = int(color[2:4], 16)
 36        b = int(color[4:6], 16)
 37        return r + g + b
 38    
 39    @property
 40    def percentage_painted(self):
 41        return self._percentage_painted
 42    
 43    @property
 44    def colored_upper_side_strength(self):
 45        strength = 0.0
 46        total = 0.0
 47        for color, percentage in self._color:
 48            if total < 50.0:
 49                strength += self.calculate_color_strength(color) * (percentage / 50.0)
 50                total += percentage
 51        return strength if total > 0.0 else -1.0
 52
 53    @property
 54    def colored_lower_side_strength(self):
 55         #calculate the strength of the second 50% of the egg
 56        strength = 0.0
 57        total = 0.0
 58        for color, percentage in self._color:
 59            if total < 50.0:
 60                total += percentage
 61                continue
 62
 63            strength += self.calculate_color_strength(color) * (percentage / 50.0)
 64            total += percentage
 65        return strength if total > 50.0 else -1.0
 66    
 67    def __mul__(self, other):
 68        if not isinstance(other, Egg):
 69            raise ValueError("Egg can only hit another Egg")
 70        
 71        if self._top_broken or other._top_broken:
 72            raise TypeError("Cannot hit with a broken top")
 73        
 74        if self.colored_upper_side_strength > other.colored_upper_side_strength:
 75            other._top_broken = True
 76            if self.tournament is not None and self.tournament is other.tournament:
 77                self.tournament.record_match(self, other, "top")   
 78            return self
 79        else:
 80            self._top_broken = True
 81            if self.tournament is not None and self.tournament is other.tournament:
 82                self.tournament.record_match(other, self, "top")
 83            return other
 84
 85    def __matmul__(self, other):
 86        if not isinstance(other, Egg):
 87            raise ValueError("Egg can only hit another Egg")
 88        
 89        if self._bottom_broken or other._bottom_broken:
 90            raise TypeError("Cannot hit with a broken bottom")
 91        
 92        if self.colored_lower_side_strength > other.colored_lower_side_strength:
 93            other._bottom_broken = True
 94            if self.tournament is not None and self.tournament is other.tournament:
 95                self.tournament.record_match(self, other, "bottom")
 96            return self
 97        else:
 98            self._bottom_broken = True
 99            if self.tournament is not None and self.tournament is other.tournament:
100                self.tournament.record_match(other, self, "bottom")
101            return other
102        
103
104
105class EggTournament:
106    def __init__(self):
107        self._participants = {}
108        self._history = {}
109
110    def register(self, egg, egg_name):
111        if not isinstance(egg, Egg):
112            raise ValueError("Only Eggs can participate in the tournament")
113        
114        if egg.tournament is not None:
115            raise ValueError("An egg cannot be registered in multiple tournaments")
116        
117        if not egg_name.isidentifier() or keyword.iskeyword(egg_name):
118            raise ValueError("Invalid registration name") 
119        
120        if egg_name in self._participants:
121            raise ValueError(f"Egg with name {egg_name} has already been registered")
122      
123        self._participants[egg_name] = egg
124        egg.tournament = self
125
126    def __getitem__(self, item):
127        if isinstance(item, tuple) and len(item) == 3:
128            egg1, egg2, type = item
129        elif isinstance(item, slice):
130            egg1 = item.start
131            egg2 = item.stop
132            type = item.step
133        else:
134            raise KeyError("Invalid input format.")
135            
136        key = (frozenset([egg1, egg2]), type)
137        if key not in self._history:
138            raise KeyError("No match history for the given eggs and type.")
139        return self._history[key]
140    
141    def record_match(self, winner, loser, type):
142        key = (frozenset([winner, loser]), type)
143        self._history[key] = winner
144
145    def __rmatmul__(self, rank):
146        if not isinstance(rank, int) or rank < 1:
147            raise ValueError("Rank must be a positive integer")
148        
149        wins = {egg: 0 for egg in self._participants.values()}
150        for winner in self._history.values():
151            if winner in wins:
152                wins[winner] += 1
153
154        win_groups = {}
155        for egg, win_count in wins.items():
156            if win_count not in win_groups:
157                win_groups[win_count] = set()
158            win_groups[win_count].add(egg)
159
160        sorted_win_counts = sorted(win_groups.keys(), reverse=True)
161        if rank > len(sorted_win_counts):
162            raise IndexError("Rank not found in the tournament")
163
164        eggs_at_rank = win_groups[sorted_win_counts[rank - 1]]
165        if len(eggs_at_rank) == 1:
166            return next(iter(eggs_at_rank))
167        else:
168            return eggs_at_rank
169    
170    def __getattr__(self, name):
171        if name not in self._participants:
172            raise AttributeError("Apologies, there is no such egg registered")
173        
174        target = self._participants[name]
175        wins = {egg: 0 for egg in self._participants.values()}
176        for winner in self._history.values():
177            if winner in wins:
178                wins[winner] += 1
179
180        victories = wins[target]
181        unique_wins = sorted(list(set(wins.values())), reverse=True)
182        pos = unique_wins.index(victories) + 1
183
184        return {"position" : pos, "victories": victories}
185
186    def __contains__(self, egg):
187        return egg in self._participants.values()

..............................................
----------------------------------------------------------------------
Ran 46 tests in 0.001s

OK

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