1import math
  2
  3MAX_INT = math.inf
  4MAX_URANIUM = 20
  5
  6class Candy:
  7    def __init__(self, mass, uranium):
  8        self.__mass = mass
  9        self.__uranium = uranium
 10
 11    def get_uranium_quantity(self):
 12        return self.__mass * self.__uranium
 13
 14    def get_mass(self):
 15        return self.__mass
 16
 17
 18class Person:
 19    def __init__(self, tuple_of_coordinates):
 20        self.tuple_of_coordinates = tuple_of_coordinates
 21
 22    def set_position(self, new_tuple_of_coordinates):
 23        self.tuple_of_coordinates = new_tuple_of_coordinates
 24
 25    def get_position(self):
 26        return self.tuple_of_coordinates
 27
 28
 29class Kid(Person):
 30    def __init__(self, tuple_of_coordinates, initiative):
 31        super().__init__(tuple_of_coordinates)
 32        self.__initiative = initiative
 33        self.box_of_candies = []
 34        self._level_of_uranium = 0.0
 35        self.sorted_hosts = []
 36        self.is_adult = False
 37        self.is_alive = True
 38
 39    def get_initiative(self):
 40        return self.__initiative
 41
 42    def add_candy(self, candy):
 43        self.box_of_candies.append(candy)
 44        self._level_of_uranium += candy.get_uranium_quantity()
 45
 46    def is_critical(self):
 47        return self._level_of_uranium > MAX_URANIUM
 48
 49    def __gt__(self, other):
 50        return self.get_initiative() > other.get_initiative()
 51
 52
 53class Host(Person):
 54    def __init__(self, tuple_of_coordinates, candies):
 55        super().__init__(tuple_of_coordinates)
 56        self.__candies = candies
 57        self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies]
 58        self.is_adult = True
 59        self.sorted_kids = []
 60
 61    @staticmethod
 62    def heaviest_candy(list_of_candies):
 63        max_candy = None
 64        max_candy_size = 0
 65        for candy in list_of_candies:
 66            if candy.get_mass() > max_candy_size:
 67                max_candy_size = candy.get_mass()
 68                max_candy = candy
 69
 70        return max_candy
 71
 72    @property
 73    def is_out_of_candy(self):
 74        return len(self.box_of_candies) == 0
 75
 76    def remove_candy(self, remove_candy_algorithm):
 77        if self.is_out_of_candy:
 78            return None
 79        return remove_candy_algorithm
 80
 81    def remove_candy_by_mass(self, list_of_candies):
 82        list_of_candies.remove(self.heaviest_candy(list_of_candies))
 83        return self.heaviest_candy(list_of_candies)
 84
 85
 86class FluxCapacitor:
 87    def __init__(self, participants):
 88        self.participants = participants
 89        self.kids = {}
 90        self.hosts = {}
 91        self.classify_participants()
 92
 93    @staticmethod
 94    def unalive_person(dict_of_people, person, is_alive):
 95        dict_of_people[person] = is_alive
 96
 97    @staticmethod
 98    def get_closest_distance_to_host(dict_of_hosts, target_coordinates):
 99        list_of_hosts = [host for host in dict_of_hosts]
100        min_distance = MAX_INT
101        min_coordinates = (MAX_INT, MAX_INT)
102        closest_host = None
103        for host in list_of_hosts:
104            tuple_of_coordinates = host.get_position()
105            distance = math.dist(tuple_of_coordinates, target_coordinates)
106            if distance < min_distance:
107                min_distance = distance
108                min_coordinates = tuple_of_coordinates
109                closest_host = host
110            elif distance == min_distance:
111                if tuple_of_coordinates[0] < min_coordinates[0]:
112                    min_coordinates = tuple_of_coordinates
113                    closest_host = host
114                elif tuple_of_coordinates[0] == min_coordinates[0]:
115                    min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] > min_coordinates[1] else min_coordinates
116                    closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host
117        return closest_host
118
119
120    def sort_hosts_by_distance_from_kid(self, kid):
121        copy_of_hosts = self.hosts.copy()
122        while len(copy_of_hosts) != 0:
123            closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position())
124            if closest_host not in kid.sorted_hosts:
125                kid.sorted_hosts.append(closest_host)
126            popped = copy_of_hosts.pop(closest_host)
127
128        return kid.sorted_hosts
129
130    def sort_kids_by_initiative_for_host(self, host):
131        copy_of_kids = self.kids.copy()
132        for kid in copy_of_kids:
133            if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()):
134                if kid not in host.sorted_kids and self.kids[kid] == False:
135                    host.sorted_kids.append(kid)
136        host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True)
137        return host.sorted_kids
138
139    def classify_participants(self):
140        for person in self.participants:
141            if not person.is_adult:
142                self.unalive_person(self.kids, person, False)
143            else:
144                if len(person.box_of_candies) != 0:
145                   self.unalive_person(self.hosts, person, False)
146
147    def get_victim(self):
148        dead_children = set()
149
150        while True:
151            if not self.hosts:
152                if bool(dead_children) != 0:
153                    return dead_children
154                else:
155                    return None
156            for kid in self.kids:
157                self.sort_hosts_by_distance_from_kid(kid)
158                closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position())
159
160                if self.kids[kid] is True:
161                    if kid in closest_host.sorted_kids:
162                        closest_host.sorted_kids.remove(kid)
163                    continue
164
165                try:
166                    out_of_candy = closest_host.is_out_of_candy
167                except AttributeError:
168                    continue
169
170                if closest_host.is_out_of_candy:
171                    kid.set_position(closest_host.get_position())
172
173                    if closest_host in kid.sorted_hosts:
174                        kid.sorted_hosts.remove(closest_host)
175                    continue
176
177                self.sort_kids_by_initiative_for_host(closest_host)
178                if kid == closest_host.sorted_kids[0]:
179
180                    given_candy = closest_host.heaviest_candy(closest_host.box_of_candies)
181                    kid.add_candy(given_candy)
182                    closest_host.remove_candy_by_mass(closest_host.box_of_candies)
183
184                    kid.set_position(closest_host.get_position())
185
186                    closest_host.sorted_kids.remove(kid)
187                    kid.sorted_hosts.remove(closest_host)
188
189                if kid.is_critical():
190                    dead_children.add(kid)
191                    self.unalive_person(self.kids, kid, True)
192
193                if closest_host.is_out_of_candy:
194                    self.hosts.pop(closest_host)
195
196            if bool(dead_children) != 0:
197                 return dead_children
198
199        return dead_children
...F..E.....
======================================================================
ERROR: test_basic_usage (test.HostTest)
Test basic usage of Host class.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/test.py", line 66, in test_basic_usage
    self.assertEqual(candy.get_mass(), 456)
AttributeError: 'function' object has no attribute 'get_mass'
======================================================================
FAIL: test_empty_kids (test.FluxCapacitorTest)
Test with empty kids.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 82, in new_function
    return function(*args, **kwargs)
  File "/tmp/test.py", line 96, in test_empty_kids
    self.assertEqual(flux_capacitor.get_victim(), None)
  File "/tmp/solution.py", line 196, in get_victim
    if bool(dead_children) != 0:
  File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 69, in handler
    _raise_exception(timeout_exception, exception_message)
  File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 45, in _raise_exception
    raise exception()
timeout_decorator.timeout_decorator.TimeoutError: 'Timed Out'
----------------------------------------------------------------------
Ran 12 tests in 0.201s
FAILED (failures=1, errors=1)
|   
        Георги Кунчев
         07.11.2023 16:04Логиката в последния ти метод е доста дълга. Не мога да я проследя. Бих посъветвал да делигираш малко от тази работа на отделни методи. Разбира се, като се отключат домашните, можеш да видиш и работата на останалите, където има доста кратки версии. | 
| f | 1 | import math | f | 1 | import math | 
| 2 | 2 | ||||
| 3 | MAX_INT = math.inf | 3 | MAX_INT = math.inf | ||
| 4 | MAX_URANIUM = 20 | 4 | MAX_URANIUM = 20 | ||
| 5 | 5 | ||||
| 6 | class Candy: | 6 | class Candy: | ||
| 7 | def __init__(self, mass, uranium): | 7 | def __init__(self, mass, uranium): | ||
| 8 | self.__mass = mass | 8 | self.__mass = mass | ||
| 9 | self.__uranium = uranium | 9 | self.__uranium = uranium | ||
| 10 | 10 | ||||
| 11 | def get_uranium_quantity(self): | 11 | def get_uranium_quantity(self): | ||
| 12 | return self.__mass * self.__uranium | 12 | return self.__mass * self.__uranium | ||
| 13 | 13 | ||||
| 14 | def get_mass(self): | 14 | def get_mass(self): | ||
| 15 | return self.__mass | 15 | return self.__mass | ||
| 16 | 16 | ||||
| 17 | 17 | ||||
| 18 | class Person: | 18 | class Person: | ||
| 19 | def __init__(self, tuple_of_coordinates): | 19 | def __init__(self, tuple_of_coordinates): | ||
| 20 | self.tuple_of_coordinates = tuple_of_coordinates | 20 | self.tuple_of_coordinates = tuple_of_coordinates | ||
| 21 | 21 | ||||
| 22 | def set_position(self, new_tuple_of_coordinates): | 22 | def set_position(self, new_tuple_of_coordinates): | ||
| 23 | self.tuple_of_coordinates = new_tuple_of_coordinates | 23 | self.tuple_of_coordinates = new_tuple_of_coordinates | ||
| 24 | 24 | ||||
| 25 | def get_position(self): | 25 | def get_position(self): | ||
| 26 | return self.tuple_of_coordinates | 26 | return self.tuple_of_coordinates | ||
| 27 | 27 | ||||
| 28 | 28 | ||||
| 29 | class Kid(Person): | 29 | class Kid(Person): | ||
| 30 | def __init__(self, tuple_of_coordinates, initiative): | 30 | def __init__(self, tuple_of_coordinates, initiative): | ||
| 31 | super().__init__(tuple_of_coordinates) | 31 | super().__init__(tuple_of_coordinates) | ||
| 32 | self.__initiative = initiative | 32 | self.__initiative = initiative | ||
| 33 | self.box_of_candies = [] | 33 | self.box_of_candies = [] | ||
| 34 | self._level_of_uranium = 0.0 | 34 | self._level_of_uranium = 0.0 | ||
| 35 | self.sorted_hosts = [] | 35 | self.sorted_hosts = [] | ||
| 36 | self.is_adult = False | 36 | self.is_adult = False | ||
| 37 | self.is_alive = True | 37 | self.is_alive = True | ||
| 38 | 38 | ||||
| 39 | def get_initiative(self): | 39 | def get_initiative(self): | ||
| 40 | return self.__initiative | 40 | return self.__initiative | ||
| 41 | 41 | ||||
| 42 | def add_candy(self, candy): | 42 | def add_candy(self, candy): | ||
| 43 | self.box_of_candies.append(candy) | 43 | self.box_of_candies.append(candy) | ||
| 44 | self._level_of_uranium += candy.get_uranium_quantity() | 44 | self._level_of_uranium += candy.get_uranium_quantity() | ||
| 45 | 45 | ||||
| 46 | def is_critical(self): | 46 | def is_critical(self): | ||
| 47 | return self._level_of_uranium > MAX_URANIUM | 47 | return self._level_of_uranium > MAX_URANIUM | ||
| 48 | 48 | ||||
| 49 | def __gt__(self, other): | 49 | def __gt__(self, other): | ||
| 50 | return self.get_initiative() > other.get_initiative() | 50 | return self.get_initiative() > other.get_initiative() | ||
| 51 | 51 | ||||
| 52 | 52 | ||||
| 53 | class Host(Person): | 53 | class Host(Person): | ||
| 54 | def __init__(self, tuple_of_coordinates, candies): | 54 | def __init__(self, tuple_of_coordinates, candies): | ||
| 55 | super().__init__(tuple_of_coordinates) | 55 | super().__init__(tuple_of_coordinates) | ||
| 56 | self.__candies = candies | 56 | self.__candies = candies | ||
| 57 | self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies] | 57 | self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies] | ||
| 58 | self.is_adult = True | 58 | self.is_adult = True | ||
| 59 | self.sorted_kids = [] | 59 | self.sorted_kids = [] | ||
| 60 | 60 | ||||
| 61 | @staticmethod | 61 | @staticmethod | ||
| 62 | def heaviest_candy(list_of_candies): | 62 | def heaviest_candy(list_of_candies): | ||
| 63 | max_candy = None | 63 | max_candy = None | ||
| 64 | max_candy_size = 0 | 64 | max_candy_size = 0 | ||
| 65 | for candy in list_of_candies: | 65 | for candy in list_of_candies: | ||
| 66 | if candy.get_mass() > max_candy_size: | 66 | if candy.get_mass() > max_candy_size: | ||
| 67 | max_candy_size = candy.get_mass() | 67 | max_candy_size = candy.get_mass() | ||
| 68 | max_candy = candy | 68 | max_candy = candy | ||
| 69 | 69 | ||||
| 70 | return max_candy | 70 | return max_candy | ||
| 71 | 71 | ||||
| 72 | @property | 72 | @property | ||
| 73 | def is_out_of_candy(self): | 73 | def is_out_of_candy(self): | ||
| 74 | return len(self.box_of_candies) == 0 | 74 | return len(self.box_of_candies) == 0 | ||
| 75 | 75 | ||||
| 76 | def remove_candy(self, remove_candy_algorithm): | 76 | def remove_candy(self, remove_candy_algorithm): | ||
| 77 | if self.is_out_of_candy: | 77 | if self.is_out_of_candy: | ||
| 78 | return None | 78 | return None | ||
| 79 | return remove_candy_algorithm | 79 | return remove_candy_algorithm | ||
| 80 | 80 | ||||
| 81 | def remove_candy_by_mass(self, list_of_candies): | 81 | def remove_candy_by_mass(self, list_of_candies): | ||
| 82 | list_of_candies.remove(self.heaviest_candy(list_of_candies)) | 82 | list_of_candies.remove(self.heaviest_candy(list_of_candies)) | ||
| 83 | return self.heaviest_candy(list_of_candies) | 83 | return self.heaviest_candy(list_of_candies) | ||
| 84 | 84 | ||||
| 85 | 85 | ||||
| 86 | class FluxCapacitor: | 86 | class FluxCapacitor: | ||
| 87 | def __init__(self, participants): | 87 | def __init__(self, participants): | ||
| 88 | self.participants = participants | 88 | self.participants = participants | ||
| 89 | self.kids = {} | 89 | self.kids = {} | ||
| 90 | self.hosts = {} | 90 | self.hosts = {} | ||
| 91 | self.classify_participants() | 91 | self.classify_participants() | ||
| 92 | 92 | ||||
| 93 | @staticmethod | 93 | @staticmethod | ||
| 94 | def unalive_person(dict_of_people, person, is_alive): | 94 | def unalive_person(dict_of_people, person, is_alive): | ||
| 95 | dict_of_people[person] = is_alive | 95 | dict_of_people[person] = is_alive | ||
| 96 | 96 | ||||
| 97 | @staticmethod | 97 | @staticmethod | ||
| 98 | def get_closest_distance_to_host(dict_of_hosts, target_coordinates): | 98 | def get_closest_distance_to_host(dict_of_hosts, target_coordinates): | ||
| 99 | list_of_hosts = [host for host in dict_of_hosts] | 99 | list_of_hosts = [host for host in dict_of_hosts] | ||
| t | 100 | #print(list_of_hosts) | t | ||
| 101 | min_distance = MAX_INT | 100 | min_distance = MAX_INT | ||
| 102 | min_coordinates = (MAX_INT, MAX_INT) | 101 | min_coordinates = (MAX_INT, MAX_INT) | ||
| 103 | closest_host = None | 102 | closest_host = None | ||
| 104 | for host in list_of_hosts: | 103 | for host in list_of_hosts: | ||
| 105 | tuple_of_coordinates = host.get_position() | 104 | tuple_of_coordinates = host.get_position() | ||
| 106 | distance = math.dist(tuple_of_coordinates, target_coordinates) | 105 | distance = math.dist(tuple_of_coordinates, target_coordinates) | ||
| 107 | if distance < min_distance: | 106 | if distance < min_distance: | ||
| 108 | min_distance = distance | 107 | min_distance = distance | ||
| 109 | min_coordinates = tuple_of_coordinates | 108 | min_coordinates = tuple_of_coordinates | ||
| 110 | closest_host = host | 109 | closest_host = host | ||
| 111 | elif distance == min_distance: | 110 | elif distance == min_distance: | ||
| 112 | if tuple_of_coordinates[0] < min_coordinates[0]: | 111 | if tuple_of_coordinates[0] < min_coordinates[0]: | ||
| 113 | min_coordinates = tuple_of_coordinates | 112 | min_coordinates = tuple_of_coordinates | ||
| 114 | closest_host = host | 113 | closest_host = host | ||
| 115 | elif tuple_of_coordinates[0] == min_coordinates[0]: | 114 | elif tuple_of_coordinates[0] == min_coordinates[0]: | ||
| 116 | min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] > min_coordinates[1] else min_coordinates | 115 | min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] > min_coordinates[1] else min_coordinates | ||
| 117 | closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host | 116 | closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host | ||
| 118 | return closest_host | 117 | return closest_host | ||
| 119 | 118 | ||||
| 120 | 119 | ||||
| 121 | def sort_hosts_by_distance_from_kid(self, kid): | 120 | def sort_hosts_by_distance_from_kid(self, kid): | ||
| 122 | copy_of_hosts = self.hosts.copy() | 121 | copy_of_hosts = self.hosts.copy() | ||
| 123 | while len(copy_of_hosts) != 0: | 122 | while len(copy_of_hosts) != 0: | ||
| 124 | closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position()) | 123 | closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position()) | ||
| 125 | if closest_host not in kid.sorted_hosts: | 124 | if closest_host not in kid.sorted_hosts: | ||
| 126 | kid.sorted_hosts.append(closest_host) | 125 | kid.sorted_hosts.append(closest_host) | ||
| 127 | popped = copy_of_hosts.pop(closest_host) | 126 | popped = copy_of_hosts.pop(closest_host) | ||
| 128 | 127 | ||||
| 129 | return kid.sorted_hosts | 128 | return kid.sorted_hosts | ||
| 130 | 129 | ||||
| 131 | def sort_kids_by_initiative_for_host(self, host): | 130 | def sort_kids_by_initiative_for_host(self, host): | ||
| 132 | copy_of_kids = self.kids.copy() | 131 | copy_of_kids = self.kids.copy() | ||
| 133 | for kid in copy_of_kids: | 132 | for kid in copy_of_kids: | ||
| 134 | if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()): | 133 | if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()): | ||
| 135 | if kid not in host.sorted_kids and self.kids[kid] == False: | 134 | if kid not in host.sorted_kids and self.kids[kid] == False: | ||
| 136 | host.sorted_kids.append(kid) | 135 | host.sorted_kids.append(kid) | ||
| 137 | host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True) | 136 | host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True) | ||
| 138 | return host.sorted_kids | 137 | return host.sorted_kids | ||
| 139 | 138 | ||||
| 140 | def classify_participants(self): | 139 | def classify_participants(self): | ||
| 141 | for person in self.participants: | 140 | for person in self.participants: | ||
| 142 | if not person.is_adult: | 141 | if not person.is_adult: | ||
| 143 | self.unalive_person(self.kids, person, False) | 142 | self.unalive_person(self.kids, person, False) | ||
| 144 | else: | 143 | else: | ||
| 145 | if len(person.box_of_candies) != 0: | 144 | if len(person.box_of_candies) != 0: | ||
| 146 | self.unalive_person(self.hosts, person, False) | 145 | self.unalive_person(self.hosts, person, False) | ||
| 147 | 146 | ||||
| 148 | def get_victim(self): | 147 | def get_victim(self): | ||
| 149 | dead_children = set() | 148 | dead_children = set() | ||
| 150 | 149 | ||||
| 151 | while True: | 150 | while True: | ||
| 152 | if not self.hosts: | 151 | if not self.hosts: | ||
| 153 | if bool(dead_children) != 0: | 152 | if bool(dead_children) != 0: | ||
| 154 | return dead_children | 153 | return dead_children | ||
| 155 | else: | 154 | else: | ||
| 156 | return None | 155 | return None | ||
| 157 | for kid in self.kids: | 156 | for kid in self.kids: | ||
| 158 | self.sort_hosts_by_distance_from_kid(kid) | 157 | self.sort_hosts_by_distance_from_kid(kid) | ||
| 159 | closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position()) | 158 | closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position()) | ||
| 160 | 159 | ||||
| 161 | if self.kids[kid] is True: | 160 | if self.kids[kid] is True: | ||
| 162 | if kid in closest_host.sorted_kids: | 161 | if kid in closest_host.sorted_kids: | ||
| 163 | closest_host.sorted_kids.remove(kid) | 162 | closest_host.sorted_kids.remove(kid) | ||
| 164 | continue | 163 | continue | ||
| 165 | 164 | ||||
| 166 | try: | 165 | try: | ||
| 167 | out_of_candy = closest_host.is_out_of_candy | 166 | out_of_candy = closest_host.is_out_of_candy | ||
| 168 | except AttributeError: | 167 | except AttributeError: | ||
| 169 | continue | 168 | continue | ||
| 170 | 169 | ||||
| 171 | if closest_host.is_out_of_candy: | 170 | if closest_host.is_out_of_candy: | ||
| 172 | kid.set_position(closest_host.get_position()) | 171 | kid.set_position(closest_host.get_position()) | ||
| 173 | 172 | ||||
| 174 | if closest_host in kid.sorted_hosts: | 173 | if closest_host in kid.sorted_hosts: | ||
| 175 | kid.sorted_hosts.remove(closest_host) | 174 | kid.sorted_hosts.remove(closest_host) | ||
| 176 | continue | 175 | continue | ||
| 177 | 176 | ||||
| 178 | self.sort_kids_by_initiative_for_host(closest_host) | 177 | self.sort_kids_by_initiative_for_host(closest_host) | ||
| 179 | if kid == closest_host.sorted_kids[0]: | 178 | if kid == closest_host.sorted_kids[0]: | ||
| 180 | 179 | ||||
| 181 | given_candy = closest_host.heaviest_candy(closest_host.box_of_candies) | 180 | given_candy = closest_host.heaviest_candy(closest_host.box_of_candies) | ||
| 182 | kid.add_candy(given_candy) | 181 | kid.add_candy(given_candy) | ||
| 183 | closest_host.remove_candy_by_mass(closest_host.box_of_candies) | 182 | closest_host.remove_candy_by_mass(closest_host.box_of_candies) | ||
| 184 | 183 | ||||
| 185 | kid.set_position(closest_host.get_position()) | 184 | kid.set_position(closest_host.get_position()) | ||
| 186 | 185 | ||||
| 187 | closest_host.sorted_kids.remove(kid) | 186 | closest_host.sorted_kids.remove(kid) | ||
| 188 | kid.sorted_hosts.remove(closest_host) | 187 | kid.sorted_hosts.remove(closest_host) | ||
| 189 | 188 | ||||
| 190 | if kid.is_critical(): | 189 | if kid.is_critical(): | ||
| 191 | dead_children.add(kid) | 190 | dead_children.add(kid) | ||
| 192 | self.unalive_person(self.kids, kid, True) | 191 | self.unalive_person(self.kids, kid, True) | ||
| 193 | 192 | ||||
| 194 | if closest_host.is_out_of_candy: | 193 | if closest_host.is_out_of_candy: | ||
| 195 | self.hosts.pop(closest_host) | 194 | self.hosts.pop(closest_host) | ||
| 196 | 195 | ||||
| 197 | if bool(dead_children) != 0: | 196 | if bool(dead_children) != 0: | ||
| 198 | return dead_children | 197 | return dead_children | ||
| 199 | 198 | ||||
| 200 | return dead_children | 199 | return dead_children | ||
| 201 | 200 | ||||
| 202 | 201 | 
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 
 | 
 | |||||||||
| f | 1 | import math | f | 1 | import math | 
| 2 | 2 | ||||
| 3 | MAX_INT = math.inf | 3 | MAX_INT = math.inf | ||
| 4 | MAX_URANIUM = 20 | 4 | MAX_URANIUM = 20 | ||
| 5 | 5 | ||||
| 6 | class Candy: | 6 | class Candy: | ||
| 7 | def __init__(self, mass, uranium): | 7 | def __init__(self, mass, uranium): | ||
| 8 | self.__mass = mass | 8 | self.__mass = mass | ||
| 9 | self.__uranium = uranium | 9 | self.__uranium = uranium | ||
| 10 | 10 | ||||
| 11 | def get_uranium_quantity(self): | 11 | def get_uranium_quantity(self): | ||
| 12 | return self.__mass * self.__uranium | 12 | return self.__mass * self.__uranium | ||
| 13 | 13 | ||||
| 14 | def get_mass(self): | 14 | def get_mass(self): | ||
| 15 | return self.__mass | 15 | return self.__mass | ||
| 16 | 16 | ||||
| 17 | 17 | ||||
| 18 | class Person: | 18 | class Person: | ||
| 19 | def __init__(self, tuple_of_coordinates): | 19 | def __init__(self, tuple_of_coordinates): | ||
| 20 | self.tuple_of_coordinates = tuple_of_coordinates | 20 | self.tuple_of_coordinates = tuple_of_coordinates | ||
| 21 | 21 | ||||
| 22 | def set_position(self, new_tuple_of_coordinates): | 22 | def set_position(self, new_tuple_of_coordinates): | ||
| 23 | self.tuple_of_coordinates = new_tuple_of_coordinates | 23 | self.tuple_of_coordinates = new_tuple_of_coordinates | ||
| 24 | 24 | ||||
| 25 | def get_position(self): | 25 | def get_position(self): | ||
| 26 | return self.tuple_of_coordinates | 26 | return self.tuple_of_coordinates | ||
| 27 | 27 | ||||
| 28 | 28 | ||||
| 29 | class Kid(Person): | 29 | class Kid(Person): | ||
| 30 | def __init__(self, tuple_of_coordinates, initiative): | 30 | def __init__(self, tuple_of_coordinates, initiative): | ||
| 31 | super().__init__(tuple_of_coordinates) | 31 | super().__init__(tuple_of_coordinates) | ||
| 32 | self.__initiative = initiative | 32 | self.__initiative = initiative | ||
| 33 | self.box_of_candies = [] | 33 | self.box_of_candies = [] | ||
| 34 | self._level_of_uranium = 0.0 | 34 | self._level_of_uranium = 0.0 | ||
| 35 | self.sorted_hosts = [] | 35 | self.sorted_hosts = [] | ||
| 36 | self.is_adult = False | 36 | self.is_adult = False | ||
| 37 | self.is_alive = True | 37 | self.is_alive = True | ||
| 38 | 38 | ||||
| 39 | def get_initiative(self): | 39 | def get_initiative(self): | ||
| 40 | return self.__initiative | 40 | return self.__initiative | ||
| 41 | 41 | ||||
| 42 | def add_candy(self, candy): | 42 | def add_candy(self, candy): | ||
| 43 | self.box_of_candies.append(candy) | 43 | self.box_of_candies.append(candy) | ||
| 44 | self._level_of_uranium += candy.get_uranium_quantity() | 44 | self._level_of_uranium += candy.get_uranium_quantity() | ||
| 45 | 45 | ||||
| 46 | def is_critical(self): | 46 | def is_critical(self): | ||
| 47 | return self._level_of_uranium > MAX_URANIUM | 47 | return self._level_of_uranium > MAX_URANIUM | ||
| 48 | 48 | ||||
| 49 | def __gt__(self, other): | 49 | def __gt__(self, other): | ||
| 50 | return self.get_initiative() > other.get_initiative() | 50 | return self.get_initiative() > other.get_initiative() | ||
| 51 | 51 | ||||
| 52 | 52 | ||||
| 53 | class Host(Person): | 53 | class Host(Person): | ||
| 54 | def __init__(self, tuple_of_coordinates, candies): | 54 | def __init__(self, tuple_of_coordinates, candies): | ||
| 55 | super().__init__(tuple_of_coordinates) | 55 | super().__init__(tuple_of_coordinates) | ||
| 56 | self.__candies = candies | 56 | self.__candies = candies | ||
| 57 | self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies] | 57 | self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies] | ||
| 58 | self.is_adult = True | 58 | self.is_adult = True | ||
| 59 | self.sorted_kids = [] | 59 | self.sorted_kids = [] | ||
| 60 | 60 | ||||
| 61 | @staticmethod | 61 | @staticmethod | ||
| 62 | def heaviest_candy(list_of_candies): | 62 | def heaviest_candy(list_of_candies): | ||
| 63 | max_candy = None | 63 | max_candy = None | ||
| 64 | max_candy_size = 0 | 64 | max_candy_size = 0 | ||
| 65 | for candy in list_of_candies: | 65 | for candy in list_of_candies: | ||
| 66 | if candy.get_mass() > max_candy_size: | 66 | if candy.get_mass() > max_candy_size: | ||
| 67 | max_candy_size = candy.get_mass() | 67 | max_candy_size = candy.get_mass() | ||
| 68 | max_candy = candy | 68 | max_candy = candy | ||
| 69 | 69 | ||||
| 70 | return max_candy | 70 | return max_candy | ||
| 71 | 71 | ||||
| 72 | @property | 72 | @property | ||
| 73 | def is_out_of_candy(self): | 73 | def is_out_of_candy(self): | ||
| 74 | return len(self.box_of_candies) == 0 | 74 | return len(self.box_of_candies) == 0 | ||
| 75 | 75 | ||||
| 76 | def remove_candy(self, remove_candy_algorithm): | 76 | def remove_candy(self, remove_candy_algorithm): | ||
| 77 | if self.is_out_of_candy: | 77 | if self.is_out_of_candy: | ||
| 78 | return None | 78 | return None | ||
| 79 | return remove_candy_algorithm | 79 | return remove_candy_algorithm | ||
| 80 | 80 | ||||
| 81 | def remove_candy_by_mass(self, list_of_candies): | 81 | def remove_candy_by_mass(self, list_of_candies): | ||
| 82 | list_of_candies.remove(self.heaviest_candy(list_of_candies)) | 82 | list_of_candies.remove(self.heaviest_candy(list_of_candies)) | ||
| 83 | return self.heaviest_candy(list_of_candies) | 83 | return self.heaviest_candy(list_of_candies) | ||
| 84 | 84 | ||||
| 85 | 85 | ||||
| 86 | class FluxCapacitor: | 86 | class FluxCapacitor: | ||
| 87 | def __init__(self, participants): | 87 | def __init__(self, participants): | ||
| 88 | self.participants = participants | 88 | self.participants = participants | ||
| 89 | self.kids = {} | 89 | self.kids = {} | ||
| 90 | self.hosts = {} | 90 | self.hosts = {} | ||
| 91 | self.classify_participants() | 91 | self.classify_participants() | ||
| 92 | 92 | ||||
| 93 | @staticmethod | 93 | @staticmethod | ||
| 94 | def unalive_person(dict_of_people, person, is_alive): | 94 | def unalive_person(dict_of_people, person, is_alive): | ||
| 95 | dict_of_people[person] = is_alive | 95 | dict_of_people[person] = is_alive | ||
| 96 | 96 | ||||
| 97 | @staticmethod | 97 | @staticmethod | ||
| 98 | def get_closest_distance_to_host(dict_of_hosts, target_coordinates): | 98 | def get_closest_distance_to_host(dict_of_hosts, target_coordinates): | ||
| 99 | list_of_hosts = [host for host in dict_of_hosts] | 99 | list_of_hosts = [host for host in dict_of_hosts] | ||
| 100 | #print(list_of_hosts) | 100 | #print(list_of_hosts) | ||
| 101 | min_distance = MAX_INT | 101 | min_distance = MAX_INT | ||
| 102 | min_coordinates = (MAX_INT, MAX_INT) | 102 | min_coordinates = (MAX_INT, MAX_INT) | ||
| 103 | closest_host = None | 103 | closest_host = None | ||
| 104 | for host in list_of_hosts: | 104 | for host in list_of_hosts: | ||
| 105 | tuple_of_coordinates = host.get_position() | 105 | tuple_of_coordinates = host.get_position() | ||
| 106 | distance = math.dist(tuple_of_coordinates, target_coordinates) | 106 | distance = math.dist(tuple_of_coordinates, target_coordinates) | ||
| 107 | if distance < min_distance: | 107 | if distance < min_distance: | ||
| 108 | min_distance = distance | 108 | min_distance = distance | ||
| 109 | min_coordinates = tuple_of_coordinates | 109 | min_coordinates = tuple_of_coordinates | ||
| 110 | closest_host = host | 110 | closest_host = host | ||
| 111 | elif distance == min_distance: | 111 | elif distance == min_distance: | ||
| 112 | if tuple_of_coordinates[0] < min_coordinates[0]: | 112 | if tuple_of_coordinates[0] < min_coordinates[0]: | ||
| 113 | min_coordinates = tuple_of_coordinates | 113 | min_coordinates = tuple_of_coordinates | ||
| 114 | closest_host = host | 114 | closest_host = host | ||
| 115 | elif tuple_of_coordinates[0] == min_coordinates[0]: | 115 | elif tuple_of_coordinates[0] == min_coordinates[0]: | ||
| n | 116 | min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] < min_coordinates[1] else min_coordinates | n | 116 | min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] > min_coordinates[1] else min_coordinates | 
| 117 | closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host | 117 | closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host | ||
| 118 | return closest_host | 118 | return closest_host | ||
| 119 | 119 | ||||
| 120 | 120 | ||||
| 121 | def sort_hosts_by_distance_from_kid(self, kid): | 121 | def sort_hosts_by_distance_from_kid(self, kid): | ||
| 122 | copy_of_hosts = self.hosts.copy() | 122 | copy_of_hosts = self.hosts.copy() | ||
| 123 | while len(copy_of_hosts) != 0: | 123 | while len(copy_of_hosts) != 0: | ||
| 124 | closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position()) | 124 | closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position()) | ||
| 125 | if closest_host not in kid.sorted_hosts: | 125 | if closest_host not in kid.sorted_hosts: | ||
| 126 | kid.sorted_hosts.append(closest_host) | 126 | kid.sorted_hosts.append(closest_host) | ||
| 127 | popped = copy_of_hosts.pop(closest_host) | 127 | popped = copy_of_hosts.pop(closest_host) | ||
| 128 | 128 | ||||
| 129 | return kid.sorted_hosts | 129 | return kid.sorted_hosts | ||
| 130 | 130 | ||||
| 131 | def sort_kids_by_initiative_for_host(self, host): | 131 | def sort_kids_by_initiative_for_host(self, host): | ||
| 132 | copy_of_kids = self.kids.copy() | 132 | copy_of_kids = self.kids.copy() | ||
| 133 | for kid in copy_of_kids: | 133 | for kid in copy_of_kids: | ||
| 134 | if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()): | 134 | if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()): | ||
| 135 | if kid not in host.sorted_kids and self.kids[kid] == False: | 135 | if kid not in host.sorted_kids and self.kids[kid] == False: | ||
| 136 | host.sorted_kids.append(kid) | 136 | host.sorted_kids.append(kid) | ||
| 137 | host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True) | 137 | host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True) | ||
| 138 | return host.sorted_kids | 138 | return host.sorted_kids | ||
| 139 | 139 | ||||
| 140 | def classify_participants(self): | 140 | def classify_participants(self): | ||
| 141 | for person in self.participants: | 141 | for person in self.participants: | ||
| 142 | if not person.is_adult: | 142 | if not person.is_adult: | ||
| 143 | self.unalive_person(self.kids, person, False) | 143 | self.unalive_person(self.kids, person, False) | ||
| 144 | else: | 144 | else: | ||
| 145 | if len(person.box_of_candies) != 0: | 145 | if len(person.box_of_candies) != 0: | ||
| 146 | self.unalive_person(self.hosts, person, False) | 146 | self.unalive_person(self.hosts, person, False) | ||
| 147 | 147 | ||||
| 148 | def get_victim(self): | 148 | def get_victim(self): | ||
| 149 | dead_children = set() | 149 | dead_children = set() | ||
| 150 | 150 | ||||
| 151 | while True: | 151 | while True: | ||
| 152 | if not self.hosts: | 152 | if not self.hosts: | ||
| 153 | if bool(dead_children) != 0: | 153 | if bool(dead_children) != 0: | ||
| 154 | return dead_children | 154 | return dead_children | ||
| 155 | else: | 155 | else: | ||
| 156 | return None | 156 | return None | ||
| 157 | for kid in self.kids: | 157 | for kid in self.kids: | ||
| 158 | self.sort_hosts_by_distance_from_kid(kid) | 158 | self.sort_hosts_by_distance_from_kid(kid) | ||
| 159 | closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position()) | 159 | closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position()) | ||
| 160 | 160 | ||||
| 161 | if self.kids[kid] is True: | 161 | if self.kids[kid] is True: | ||
| 162 | if kid in closest_host.sorted_kids: | 162 | if kid in closest_host.sorted_kids: | ||
| 163 | closest_host.sorted_kids.remove(kid) | 163 | closest_host.sorted_kids.remove(kid) | ||
| 164 | continue | 164 | continue | ||
| 165 | 165 | ||||
| 166 | try: | 166 | try: | ||
| 167 | out_of_candy = closest_host.is_out_of_candy | 167 | out_of_candy = closest_host.is_out_of_candy | ||
| 168 | except AttributeError: | 168 | except AttributeError: | ||
| 169 | continue | 169 | continue | ||
| 170 | 170 | ||||
| 171 | if closest_host.is_out_of_candy: | 171 | if closest_host.is_out_of_candy: | ||
| 172 | kid.set_position(closest_host.get_position()) | 172 | kid.set_position(closest_host.get_position()) | ||
| 173 | 173 | ||||
| 174 | if closest_host in kid.sorted_hosts: | 174 | if closest_host in kid.sorted_hosts: | ||
| 175 | kid.sorted_hosts.remove(closest_host) | 175 | kid.sorted_hosts.remove(closest_host) | ||
| 176 | continue | 176 | continue | ||
| 177 | 177 | ||||
| 178 | self.sort_kids_by_initiative_for_host(closest_host) | 178 | self.sort_kids_by_initiative_for_host(closest_host) | ||
| 179 | if kid == closest_host.sorted_kids[0]: | 179 | if kid == closest_host.sorted_kids[0]: | ||
| 180 | 180 | ||||
| 181 | given_candy = closest_host.heaviest_candy(closest_host.box_of_candies) | 181 | given_candy = closest_host.heaviest_candy(closest_host.box_of_candies) | ||
| 182 | kid.add_candy(given_candy) | 182 | kid.add_candy(given_candy) | ||
| 183 | closest_host.remove_candy_by_mass(closest_host.box_of_candies) | 183 | closest_host.remove_candy_by_mass(closest_host.box_of_candies) | ||
| 184 | 184 | ||||
| 185 | kid.set_position(closest_host.get_position()) | 185 | kid.set_position(closest_host.get_position()) | ||
| 186 | 186 | ||||
| 187 | closest_host.sorted_kids.remove(kid) | 187 | closest_host.sorted_kids.remove(kid) | ||
| 188 | kid.sorted_hosts.remove(closest_host) | 188 | kid.sorted_hosts.remove(closest_host) | ||
| 189 | 189 | ||||
| 190 | if kid.is_critical(): | 190 | if kid.is_critical(): | ||
| 191 | dead_children.add(kid) | 191 | dead_children.add(kid) | ||
| 192 | self.unalive_person(self.kids, kid, True) | 192 | self.unalive_person(self.kids, kid, True) | ||
| 193 | 193 | ||||
| 194 | if closest_host.is_out_of_candy: | 194 | if closest_host.is_out_of_candy: | ||
| 195 | self.hosts.pop(closest_host) | 195 | self.hosts.pop(closest_host) | ||
| 196 | 196 | ||||
| 197 | if bool(dead_children) != 0: | 197 | if bool(dead_children) != 0: | ||
| 198 | return dead_children | 198 | return dead_children | ||
| 199 | 199 | ||||
| 200 | return dead_children | 200 | return dead_children | ||
| 201 | 201 | ||||
| 202 | 202 | ||||
| t | 203 | t | |||
| 204 | |||||
| 205 | 
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 
 | 
 | |||||||||
| f | 1 | import math | f | 1 | import math | 
| n | 2 | import sys | n | ||
| 3 | 2 | ||||
| n | 4 | MAX_INT = sys.maxsize | n | 3 | MAX_INT = math.inf | 
| 4 | MAX_URANIUM = 20 | ||||
| 5 | 5 | ||||
| 6 | class Candy: | 6 | class Candy: | ||
| 7 | def __init__(self, mass, uranium): | 7 | def __init__(self, mass, uranium): | ||
| 8 | self.__mass = mass | 8 | self.__mass = mass | ||
| 9 | self.__uranium = uranium | 9 | self.__uranium = uranium | ||
| 10 | 10 | ||||
| 11 | def get_uranium_quantity(self): | 11 | def get_uranium_quantity(self): | ||
| 12 | return self.__mass * self.__uranium | 12 | return self.__mass * self.__uranium | ||
| 13 | 13 | ||||
| 14 | def get_mass(self): | 14 | def get_mass(self): | ||
| 15 | return self.__mass | 15 | return self.__mass | ||
| n | n | 16 | |||
| 16 | 17 | ||||
| 17 | class Person: | 18 | class Person: | ||
| 18 | def __init__(self, tuple_of_coordinates): | 19 | def __init__(self, tuple_of_coordinates): | ||
| 19 | self.tuple_of_coordinates = tuple_of_coordinates | 20 | self.tuple_of_coordinates = tuple_of_coordinates | ||
| 20 | 21 | ||||
| 21 | def set_position(self, new_tuple_of_coordinates): | 22 | def set_position(self, new_tuple_of_coordinates): | ||
| 22 | self.tuple_of_coordinates = new_tuple_of_coordinates | 23 | self.tuple_of_coordinates = new_tuple_of_coordinates | ||
| 23 | 24 | ||||
| 24 | def get_position(self): | 25 | def get_position(self): | ||
| 25 | return self.tuple_of_coordinates | 26 | return self.tuple_of_coordinates | ||
| 26 | 27 | ||||
| 27 | 28 | ||||
| 28 | class Kid(Person): | 29 | class Kid(Person): | ||
| 29 | def __init__(self, tuple_of_coordinates, initiative): | 30 | def __init__(self, tuple_of_coordinates, initiative): | ||
| 30 | super().__init__(tuple_of_coordinates) | 31 | super().__init__(tuple_of_coordinates) | ||
| 31 | self.__initiative = initiative | 32 | self.__initiative = initiative | ||
| 32 | self.box_of_candies = [] | 33 | self.box_of_candies = [] | ||
| 33 | self._level_of_uranium = 0.0 | 34 | self._level_of_uranium = 0.0 | ||
| 34 | self.sorted_hosts = [] | 35 | self.sorted_hosts = [] | ||
| 35 | self.is_adult = False | 36 | self.is_adult = False | ||
| 36 | self.is_alive = True | 37 | self.is_alive = True | ||
| 37 | 38 | ||||
| 38 | def get_initiative(self): | 39 | def get_initiative(self): | ||
| 39 | return self.__initiative | 40 | return self.__initiative | ||
| 40 | 41 | ||||
| 41 | def add_candy(self, candy): | 42 | def add_candy(self, candy): | ||
| 42 | self.box_of_candies.append(candy) | 43 | self.box_of_candies.append(candy) | ||
| 43 | self._level_of_uranium += candy.get_uranium_quantity() | 44 | self._level_of_uranium += candy.get_uranium_quantity() | ||
| 44 | 45 | ||||
| 45 | def is_critical(self): | 46 | def is_critical(self): | ||
| n | 46 | if self._level_of_uranium > 20: | n | 47 | return self._level_of_uranium > MAX_URANIUM | 
| 47 | return True | ||||
| 48 | return False | ||||
| 49 | 48 | ||||
| 50 | def __gt__(self, other): | 49 | def __gt__(self, other): | ||
| 51 | return self.get_initiative() > other.get_initiative() | 50 | return self.get_initiative() > other.get_initiative() | ||
| 52 | 51 | ||||
| 53 | 52 | ||||
| 54 | class Host(Person): | 53 | class Host(Person): | ||
| 55 | def __init__(self, tuple_of_coordinates, candies): | 54 | def __init__(self, tuple_of_coordinates, candies): | ||
| 56 | super().__init__(tuple_of_coordinates) | 55 | super().__init__(tuple_of_coordinates) | ||
| 57 | self.__candies = candies | 56 | self.__candies = candies | ||
| 58 | self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies] | 57 | self.box_of_candies = [Candy(candy_params[0], candy_params[1]) for candy_params in candies] | ||
| 59 | self.is_adult = True | 58 | self.is_adult = True | ||
| 60 | self.sorted_kids = [] | 59 | self.sorted_kids = [] | ||
| 61 | 60 | ||||
| 62 | @staticmethod | 61 | @staticmethod | ||
| 63 | def heaviest_candy(list_of_candies): | 62 | def heaviest_candy(list_of_candies): | ||
| 64 | max_candy = None | 63 | max_candy = None | ||
| 65 | max_candy_size = 0 | 64 | max_candy_size = 0 | ||
| 66 | for candy in list_of_candies: | 65 | for candy in list_of_candies: | ||
| 67 | if candy.get_mass() > max_candy_size: | 66 | if candy.get_mass() > max_candy_size: | ||
| 68 | max_candy_size = candy.get_mass() | 67 | max_candy_size = candy.get_mass() | ||
| 69 | max_candy = candy | 68 | max_candy = candy | ||
| 70 | 69 | ||||
| 71 | return max_candy | 70 | return max_candy | ||
| 72 | 71 | ||||
| 73 | @property | 72 | @property | ||
| 74 | def is_out_of_candy(self): | 73 | def is_out_of_candy(self): | ||
| 75 | return len(self.box_of_candies) == 0 | 74 | return len(self.box_of_candies) == 0 | ||
| 76 | 75 | ||||
| 77 | def remove_candy(self, remove_candy_algorithm): | 76 | def remove_candy(self, remove_candy_algorithm): | ||
| 78 | if self.is_out_of_candy: | 77 | if self.is_out_of_candy: | ||
| 79 | return None | 78 | return None | ||
| 80 | return remove_candy_algorithm | 79 | return remove_candy_algorithm | ||
| 81 | 80 | ||||
| 82 | def remove_candy_by_mass(self, list_of_candies): | 81 | def remove_candy_by_mass(self, list_of_candies): | ||
| 83 | list_of_candies.remove(self.heaviest_candy(list_of_candies)) | 82 | list_of_candies.remove(self.heaviest_candy(list_of_candies)) | ||
| 84 | return self.heaviest_candy(list_of_candies) | 83 | return self.heaviest_candy(list_of_candies) | ||
| 85 | 84 | ||||
| 86 | 85 | ||||
| 87 | class FluxCapacitor: | 86 | class FluxCapacitor: | ||
| 88 | def __init__(self, participants): | 87 | def __init__(self, participants): | ||
| 89 | self.participants = participants | 88 | self.participants = participants | ||
| 90 | self.kids = {} | 89 | self.kids = {} | ||
| 91 | self.hosts = {} | 90 | self.hosts = {} | ||
| 92 | self.classify_participants() | 91 | self.classify_participants() | ||
| 93 | 92 | ||||
| 94 | @staticmethod | 93 | @staticmethod | ||
| 95 | def unalive_person(dict_of_people, person, is_alive): | 94 | def unalive_person(dict_of_people, person, is_alive): | ||
| 96 | dict_of_people[person] = is_alive | 95 | dict_of_people[person] = is_alive | ||
| 97 | 96 | ||||
| 98 | @staticmethod | 97 | @staticmethod | ||
| 99 | def get_closest_distance_to_host(dict_of_hosts, target_coordinates): | 98 | def get_closest_distance_to_host(dict_of_hosts, target_coordinates): | ||
| 100 | list_of_hosts = [host for host in dict_of_hosts] | 99 | list_of_hosts = [host for host in dict_of_hosts] | ||
| 101 | #print(list_of_hosts) | 100 | #print(list_of_hosts) | ||
| 102 | min_distance = MAX_INT | 101 | min_distance = MAX_INT | ||
| 103 | min_coordinates = (MAX_INT, MAX_INT) | 102 | min_coordinates = (MAX_INT, MAX_INT) | ||
| 104 | closest_host = None | 103 | closest_host = None | ||
| 105 | for host in list_of_hosts: | 104 | for host in list_of_hosts: | ||
| 106 | tuple_of_coordinates = host.get_position() | 105 | tuple_of_coordinates = host.get_position() | ||
| 107 | distance = math.dist(tuple_of_coordinates, target_coordinates) | 106 | distance = math.dist(tuple_of_coordinates, target_coordinates) | ||
| 108 | if distance < min_distance: | 107 | if distance < min_distance: | ||
| 109 | min_distance = distance | 108 | min_distance = distance | ||
| 110 | min_coordinates = tuple_of_coordinates | 109 | min_coordinates = tuple_of_coordinates | ||
| 111 | closest_host = host | 110 | closest_host = host | ||
| 112 | elif distance == min_distance: | 111 | elif distance == min_distance: | ||
| 113 | if tuple_of_coordinates[0] < min_coordinates[0]: | 112 | if tuple_of_coordinates[0] < min_coordinates[0]: | ||
| 114 | min_coordinates = tuple_of_coordinates | 113 | min_coordinates = tuple_of_coordinates | ||
| 115 | closest_host = host | 114 | closest_host = host | ||
| 116 | elif tuple_of_coordinates[0] == min_coordinates[0]: | 115 | elif tuple_of_coordinates[0] == min_coordinates[0]: | ||
| 117 | min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] < min_coordinates[1] else min_coordinates | 116 | min_coordinates = tuple_of_coordinates if tuple_of_coordinates[1] < min_coordinates[1] else min_coordinates | ||
| 118 | closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host | 117 | closest_host = host if tuple_of_coordinates[1] < min_coordinates[1] else closest_host | ||
| 119 | return closest_host | 118 | return closest_host | ||
| 120 | 119 | ||||
| 121 | 120 | ||||
| 122 | def sort_hosts_by_distance_from_kid(self, kid): | 121 | def sort_hosts_by_distance_from_kid(self, kid): | ||
| 123 | copy_of_hosts = self.hosts.copy() | 122 | copy_of_hosts = self.hosts.copy() | ||
| 124 | while len(copy_of_hosts) != 0: | 123 | while len(copy_of_hosts) != 0: | ||
| 125 | closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position()) | 124 | closest_host = self.get_closest_distance_to_host(copy_of_hosts, kid.get_position()) | ||
| 126 | if closest_host not in kid.sorted_hosts: | 125 | if closest_host not in kid.sorted_hosts: | ||
| 127 | kid.sorted_hosts.append(closest_host) | 126 | kid.sorted_hosts.append(closest_host) | ||
| 128 | popped = copy_of_hosts.pop(closest_host) | 127 | popped = copy_of_hosts.pop(closest_host) | ||
| 129 | 128 | ||||
| 130 | return kid.sorted_hosts | 129 | return kid.sorted_hosts | ||
| 131 | 130 | ||||
| 132 | def sort_kids_by_initiative_for_host(self, host): | 131 | def sort_kids_by_initiative_for_host(self, host): | ||
| 133 | copy_of_kids = self.kids.copy() | 132 | copy_of_kids = self.kids.copy() | ||
| n | 134 | #print(copy_of_kids) | n | ||
| 135 | for kid in copy_of_kids: | 133 | for kid in copy_of_kids: | ||
| 136 | if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()): | 134 | if host == self.get_closest_distance_to_host(self.hosts, kid.get_position()): | ||
| n | 137 | if kid not in host.sorted_kids: | n | 135 | if kid not in host.sorted_kids and self.kids[kid] == False: | 
| 138 | host.sorted_kids.append(kid) | 136 | host.sorted_kids.append(kid) | ||
| n | 139 | #popped = copy_of_kids.pop(kid) | n | ||
| 140 | #print(host.sorted_kids) | ||||
| 141 | host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True) | 137 | host.sorted_kids.sort(key=lambda kid:kid.get_initiative(), reverse=True) | ||
| 142 | return host.sorted_kids | 138 | return host.sorted_kids | ||
| 143 | 139 | ||||
| 144 | def classify_participants(self): | 140 | def classify_participants(self): | ||
| 145 | for person in self.participants: | 141 | for person in self.participants: | ||
| 146 | if not person.is_adult: | 142 | if not person.is_adult: | ||
| 147 | self.unalive_person(self.kids, person, False) | 143 | self.unalive_person(self.kids, person, False) | ||
| 148 | else: | 144 | else: | ||
| n | n | 145 | if len(person.box_of_candies) != 0: | ||
| 149 | self.unalive_person(self.hosts, person, False) | 146 | self.unalive_person(self.hosts, person, False) | ||
| 147 | |||||
| 150 | def get_victim(self): | 148 | def get_victim(self): | ||
| 151 | dead_children = set() | 149 | dead_children = set() | ||
| 152 | 150 | ||||
| 153 | while True: | 151 | while True: | ||
| 154 | if not self.hosts: | 152 | if not self.hosts: | ||
| 155 | if bool(dead_children) != 0: | 153 | if bool(dead_children) != 0: | ||
| 156 | return dead_children | 154 | return dead_children | ||
| 157 | else: | 155 | else: | ||
| 158 | return None | 156 | return None | ||
| 159 | for kid in self.kids: | 157 | for kid in self.kids: | ||
| 160 | self.sort_hosts_by_distance_from_kid(kid) | 158 | self.sort_hosts_by_distance_from_kid(kid) | ||
| 161 | closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position()) | 159 | closest_host = self.get_closest_distance_to_host(self.hosts, kid.get_position()) | ||
| 162 | 160 | ||||
| n | 163 | if self.kids[kid] == True: | n | 161 | if self.kids[kid] is True: | 
| 164 | if kid in closest_host.sorted_kids: | 162 | if kid in closest_host.sorted_kids: | ||
| 165 | closest_host.sorted_kids.remove(kid) | 163 | closest_host.sorted_kids.remove(kid) | ||
| 166 | continue | 164 | continue | ||
| 167 | 165 | ||||
| n | n | 166 | try: | ||
| 167 | out_of_candy = closest_host.is_out_of_candy | ||||
| 168 | except AttributeError: | ||||
| 169 | continue | ||||
| 170 | |||||
| 168 | if closest_host.is_out_of_candy: | 171 | if closest_host.is_out_of_candy: | ||
| 169 | kid.set_position(closest_host.get_position()) | 172 | kid.set_position(closest_host.get_position()) | ||
| 170 | 173 | ||||
| 171 | if closest_host in kid.sorted_hosts: | 174 | if closest_host in kid.sorted_hosts: | ||
| 172 | kid.sorted_hosts.remove(closest_host) | 175 | kid.sorted_hosts.remove(closest_host) | ||
| 173 | continue | 176 | continue | ||
| 174 | 177 | ||||
| 175 | self.sort_kids_by_initiative_for_host(closest_host) | 178 | self.sort_kids_by_initiative_for_host(closest_host) | ||
| 176 | if kid == closest_host.sorted_kids[0]: | 179 | if kid == closest_host.sorted_kids[0]: | ||
| 177 | 180 | ||||
| 178 | given_candy = closest_host.heaviest_candy(closest_host.box_of_candies) | 181 | given_candy = closest_host.heaviest_candy(closest_host.box_of_candies) | ||
| 179 | kid.add_candy(given_candy) | 182 | kid.add_candy(given_candy) | ||
| 180 | closest_host.remove_candy_by_mass(closest_host.box_of_candies) | 183 | closest_host.remove_candy_by_mass(closest_host.box_of_candies) | ||
| 181 | 184 | ||||
| 182 | kid.set_position(closest_host.get_position()) | 185 | kid.set_position(closest_host.get_position()) | ||
| 183 | 186 | ||||
| 184 | closest_host.sorted_kids.remove(kid) | 187 | closest_host.sorted_kids.remove(kid) | ||
| 185 | kid.sorted_hosts.remove(closest_host) | 188 | kid.sorted_hosts.remove(closest_host) | ||
| 186 | 189 | ||||
| 187 | if kid.is_critical(): | 190 | if kid.is_critical(): | ||
| 188 | dead_children.add(kid) | 191 | dead_children.add(kid) | ||
| 189 | self.unalive_person(self.kids, kid, True) | 192 | self.unalive_person(self.kids, kid, True) | ||
| 190 | 193 | ||||
| 191 | if closest_host.is_out_of_candy: | 194 | if closest_host.is_out_of_candy: | ||
| 192 | self.hosts.pop(closest_host) | 195 | self.hosts.pop(closest_host) | ||
| 193 | 196 | ||||
| 194 | if bool(dead_children) != 0: | 197 | if bool(dead_children) != 0: | ||
| 195 | return dead_children | 198 | return dead_children | ||
| 196 | 199 | ||||
| 197 | return dead_children | 200 | return dead_children | ||
| 198 | 201 | ||||
| 199 | 202 | ||||
| 200 | 203 | ||||
| 201 | 204 | ||||
| t | t | 205 | 
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 
 | 
 | |||||||||