Домашни > Хелоуин в Припят > Решения > Решението на Клементина Картевска

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

10 точки общо

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

  1import math 
  2
  3    
  4class Candy():
  5    """A candy with mass and uranium content."""
  6    def __init__(self, mass=0, uranium=0):
  7        """Initialize a candy with the given mass and uranium content."""
  8        self.mass = mass
  9        self.uranium = uranium
 10
 11    def get_uranium_quantity(self):
 12        """Calculate the uranium quantity in the candy."""
 13        return self.mass * self.uranium
 14    
 15    def get_mass(self):
 16        """Get the mass of the candy."""
 17        return self.mass
 18
 19
 20class Person():
 21    """A person with a position in a 2D space."""
 22    def __init__(self, position=(0, 0)):
 23        """Initialize a person with the given position."""
 24        self.x, self.y = position
 25
 26    def get_position(self):
 27        """Get the position of the person."""
 28        return  (self.x, self.y)
 29
 30    def set_position(self, position):
 31        """Set the position of the person."""
 32        self.x, self.y = position
 33
 34
 35class Kid(Person):
 36    def __init__(self, position=(0, 0), initiative=0):
 37        """A kid with a position, initiative, and a collection of candies."""
 38        super().__init__(position)
 39        self.initiative = initiative
 40        self.candy = []
 41        self.uranium_mass = 0
 42
 43    def get_initiative(self):
 44        """Get the initiative level of the kid."""
 45        return self.initiative
 46    
 47    def add_candy(self, candy):
 48        """Add a candy to the kid's collection and update uranium mass."""
 49        self.candy.append(candy)
 50        self.uranium_mass += candy.get_uranium_quantity()
 51
 52    def is_critical(self):
 53        """Check if the total uranium mass is critical."""
 54        return self.uranium_mass > 20
 55    
 56
 57class Host(Person):
 58    """A host with a position and a basket of candies."""
 59    def __init__(self, position, candies):
 60        """Initialize a host with the given position and candy basket."""
 61        super().__init__(position)
 62        self.candy_basket = [Candy(mass, uranium) for mass, uranium in candies]
 63
 64    def remove_candy(self, remove_func):
 65        """Remove a candy from the candy basket using a removal function."""
 66        selected_candy =  remove_func(self.candy_basket) if len(self.candy_basket) > 0 else None
 67        if selected_candy:
 68            self.candy_basket.remove(selected_candy)
 69        return selected_candy
 70    
 71
 72class FluxCapacitor():
 73    """Game simulator for kid-host interactions."""
 74    def __init__(self, participants):
 75        """Initialize the game simulator with a set of participants (kids and hosts)."""
 76        self.kids = [participant for participant in participants if isinstance(participant, Kid)]
 77        self.hosts = [participant for participant in participants if isinstance(participant, Host)]
 78        self.unvisited_hosts = {kid: list(self.hosts) for kid in self.kids}
 79        self.victims = set()
 80
 81        self._play_game()
 82
 83    def get_victim(self):
 84        """Get the victim kid(s) in the game or None if there are no victims."""
 85        return self.victims if self.victims else None        
 86
 87    def _play_game(self):
 88        """Simulate the movement of kids to the closest hosts and distribute candies."""
 89        if not self.kids or not self.hosts:
 90            return
 91        for _ in self.hosts:
 92            current_hosts = {host: [] for host in self.hosts}
 93            for kid in self.kids:
 94                closest_host = min(
 95                    self.unvisited_hosts[kid],
 96                    key=lambda host: (
 97                        self.__calculate_distance(host.get_position(), kid.get_position()),
 98                        host.get_position()[0],
 99                        host.get_position()[1]
100                    )
101                ) 
102                kid.set_position(closest_host.get_position())
103                current_hosts[closest_host].append(kid)
104                self.unvisited_hosts[kid].remove(closest_host)
105            for host, current_kids in current_hosts.items():
106                if len(current_kids) == 0:
107                    continue
108                elif len(current_kids) == 1:
109                    self._give_candy(host, current_kids[0])
110                else:
111                    current_kids.sort(key=lambda x: x.get_initiative(), reverse=True)
112                    for current_kid in current_kids:
113                        self._give_candy(host, current_kid)
114            for kid in self.kids:
115                if kid.is_critical() is True:
116                    self.victims.add(kid)
117            if self.victims:
118                return
119
120    def _give_candy(self, host, kid):
121        """Give candy from a host to a kid."""
122        candy = host.remove_candy(self.__select_candy_by_mass)
123        if candy:
124            kid.add_candy(candy)
125
126    def __calculate_distance(self, host_pos, kid_pos):
127        """Calculate the distance between a host and a kid."""
128        return math.sqrt((kid_pos[0]-host_pos[0])**2 + (kid_pos[1]-host_pos[1])**2)
129        
130    @staticmethod
131    def __select_candy_by_mass(candies):
132        """Select candy based on mass from a list of candies."""
133        return max(candies, key=lambda candy: candy.get_mass())
134    

............
----------------------------------------------------------------------
Ran 12 tests in 0.001s

OK

Дискусия
Виктор Бечев
08.11.2023 13:08

Има някои спорни моменти, като това дали е добре да извикаш `_play_game` още при инициализиране или при извикване на `get_victim`, но иначе нямам кой знае какви стилови забележки (тук таме някои от нещата, които Жорката вчера спомена, например - `if kid.is_critical() is True`, вместо просто `if kid.is_critical()`.
История
Това решение има само една версия.