1import math
  2
  3class Candy:
  4    def __init__(self, mass, uranium):
  5        self._mass = mass
  6        self._uranium = uranium
  7
  8    def get_uranium_quantity(self):
  9        return self._mass * self._uranium
 10
 11    def get_mass(self):
 12        return self._mass
 13
 14
 15class Person:
 16    def __init__(self, position):
 17        self._position = position
 18    
 19    def get_position(self):
 20        return self._position
 21    
 22    def set_position(self, position):
 23        self._position = position
 24
 25    def distance_to(self, other):
 26        return math.sqrt((self._position[0] - other._position[0])**2 
 27                         + (self._position[1] - other._position[1])**2)
 28
 29
 30class Kid(Person):
 31
 32    MAX_CANDIES = 20
 33
 34    def __init__(self, position, initiative):
 35        super().__init__(position)
 36        self._initiative = initiative
 37        self._visited_hosts = set()
 38        self._candies = set()
 39        self._uranium_in_basket = 0
 40
 41    def get_initiative(self):
 42        return self._initiative
 43    
 44    def add_candy(self, candy):
 45        self._uranium_in_basket += candy.get_uranium_quantity()
 46        self._candies.add(candy)
 47
 48    def is_critical(self):
 49        if self._uranium_in_basket > self.MAX_CANDIES:
 50            return True
 51        return False
 52    
 53    def visit(self, host):
 54        self._visited_hosts.add(host)
 55        self.set_position(host.get_position())
 56
 57    def has_visited(self, host):
 58        return host in self._visited_hosts
 59    
 60
 61class Host(Person):
 62    def __init__(self, position, candies):
 63        super().__init__(position)
 64        self._candies = []
 65        self._visitors = []
 66        for candy in candies:
 67            self._candies.append(Candy(*candy))
 68
 69    def remove_candy(self, pick_candy_func):
 70        if not self._candies:
 71            return None
 72        candy = pick_candy_func(self._candies)
 73        self._candies.remove(candy)
 74        return candy
 75        
 76    def accept_visitor(self, kid):
 77        self._visitors.append(kid)
 78
 79    def get_compare_list(self, kid):
 80        return [
 81            kid.distance_to(self),
 82            self._position[0],
 83            self._position[1],
 84            self
 85        ]
 86
 87    def give_out_candies(self, pick_candy_func):
 88        self._visitors.sort(key=lambda kid: kid.get_initiative())
 89        while self._visitors:
 90            kid = self._visitors.pop()
 91            candy = self.remove_candy(pick_candy_func)
 92            if candy is not None:
 93                kid.add_candy(candy)
 94
 95        
 96class FluxCapacitor:
 97    def __init__(self, participants):
 98        self._kids = []
 99        self._hosts = []
100        self._victims = set()
101        for participant in participants:
102            if type(participant) is Kid:
103                self._kids.append(participant)
104            if type(participant) is Host:
105                self._hosts.append(participant)
106
107    def get_victim(self):
108        kids_who_visited_all = set()
109        while (len(kids_who_visited_all) != len(self._kids) 
110               and not self._victims):
111            for kid in self._kids:
112                if kid in kids_who_visited_all:
113                    continue
114                closest_host = self._get_closest_host(kid)
115                if closest_host is None:
116                    kids_who_visited_all.add(kid)
117                    continue
118                kid.visit(closest_host)
119                closest_host.accept_visitor(kid)
120            for host in self._hosts:
121                host.give_out_candies(self._pick_candy)
122            for kid in self._kids:
123                if kid.is_critical():
124                    self._victims.add(kid)
125        return self._victims or None
126    
127    def _get_closest_host(self, kid):
128        closest_host = [None]
129        for host in self._hosts:
130            if kid.has_visited(host):
131                continue
132            if None in closest_host:
133                closest_host = host.get_compare_list(kid)
134                continue
135            closest_host = min(closest_host, host.get_compare_list(kid))
136        return closest_host[-1]
137    
138    def _pick_candy(self, candies):
139        return max(candies, key=(lambda candy: candy.get_mass()))
............
----------------------------------------------------------------------
Ran 12 tests in 0.001s
OK
                            
    
 
    
        Георги Кунчев
         
    
06.11.2023 13:11Правилно. Аз греша с моята препоръка. Избягвам да деля на редове и явно ми е убягнало. 
                            
                            
                         | 
                            
    
 
    
        Светлозар Стефанов
         
    
06.11.2023 12:32На 27-ми ред оставих брейка преди плюса, защото в pep 8 пишеше да се ползва Knuth style, за нов код който не спазва някаква предишна конвенция.
https://peps.python.org/pep-0008/#should-a-line-break-before-or-after-a-binary-operator 
                            
                            
                         | 
| f | 1 | import math | f | 1 | import math | 
| 2 | 2 | ||||
| 3 | class Candy: | 3 | class Candy: | ||
| 4 | def __init__(self, mass, uranium): | 4 | def __init__(self, mass, uranium): | ||
| n | 5 | self.__mass = mass | n | 5 | self._mass = mass | 
| 6 | self.__uranium = uranium | 6 | self._uranium = uranium | ||
| 7 | 7 | ||||
| 8 | def get_uranium_quantity(self): | 8 | def get_uranium_quantity(self): | ||
| n | 9 | return self.__mass * self.__uranium | n | 9 | return self._mass * self._uranium | 
| 10 | 10 | ||||
| 11 | def get_mass(self): | 11 | def get_mass(self): | ||
| n | 12 | return self.__mass | n | 12 | return self._mass | 
| 13 | 13 | ||||
| 14 | 14 | ||||
| 15 | class Person: | 15 | class Person: | ||
| 16 | def __init__(self, position): | 16 | def __init__(self, position): | ||
| 17 | self._position = position | 17 | self._position = position | ||
| 18 | 18 | ||||
| 19 | def get_position(self): | 19 | def get_position(self): | ||
| 20 | return self._position | 20 | return self._position | ||
| 21 | 21 | ||||
| 22 | def set_position(self, position): | 22 | def set_position(self, position): | ||
| 23 | self._position = position | 23 | self._position = position | ||
| 24 | 24 | ||||
| 25 | def distance_to(self, other): | 25 | def distance_to(self, other): | ||
| 26 | return math.sqrt((self._position[0] - other._position[0])**2 | 26 | return math.sqrt((self._position[0] - other._position[0])**2 | ||
| 27 | + (self._position[1] - other._position[1])**2) | 27 | + (self._position[1] - other._position[1])**2) | ||
| 28 | 28 | ||||
| 29 | 29 | ||||
| 30 | class Kid(Person): | 30 | class Kid(Person): | ||
| n | n | 31 | |||
| 31 | MAX_CANDIES = 20 | 32 | MAX_CANDIES = 20 | ||
| 32 | 33 | ||||
| 33 | def __init__(self, position, initiative): | 34 | def __init__(self, position, initiative): | ||
| 34 | super().__init__(position) | 35 | super().__init__(position) | ||
| n | 35 | self.__initiative = initiative | n | 36 | self._initiative = initiative | 
| 36 | self.__visited_hosts = set() | 37 | self._visited_hosts = set() | ||
| 37 | self.__candies = set() | 38 | self._candies = set() | ||
| 38 | self.__uranium_in_basket = 0 | 39 | self._uranium_in_basket = 0 | ||
| 39 | 40 | ||||
| 40 | def get_initiative(self): | 41 | def get_initiative(self): | ||
| n | 41 | return self.__initiative | n | 42 | return self._initiative | 
| 42 | 43 | ||||
| 43 | def add_candy(self, candy): | 44 | def add_candy(self, candy): | ||
| n | 44 | self.__uranium_in_basket += candy.get_uranium_quantity() | n | 45 | self._uranium_in_basket += candy.get_uranium_quantity() | 
| 45 | self.__candies.add(candy) | 46 | self._candies.add(candy) | ||
| 46 | 47 | ||||
| 47 | def is_critical(self): | 48 | def is_critical(self): | ||
| n | 48 | if self.__uranium_in_basket > Kid.MAX_CANDIES: | n | 49 | if self._uranium_in_basket > self.MAX_CANDIES: | 
| 49 | return True | 50 | return True | ||
| 50 | return False | 51 | return False | ||
| 51 | 52 | ||||
| 52 | def visit(self, host): | 53 | def visit(self, host): | ||
| n | 53 | self.__visited_hosts.add(host) | n | 54 | self._visited_hosts.add(host) | 
| 55 | self.set_position(host.get_position()) | ||||
| 54 | 56 | ||||
| 55 | def has_visited(self, host): | 57 | def has_visited(self, host): | ||
| n | 56 | return host in self.__visited_hosts | n | 58 | return host in self._visited_hosts | 
| 57 | 59 | ||||
| 58 | 60 | ||||
| 59 | class Host(Person): | 61 | class Host(Person): | ||
| 60 | def __init__(self, position, candies): | 62 | def __init__(self, position, candies): | ||
| 61 | super().__init__(position) | 63 | super().__init__(position) | ||
| n | 62 | self.__candies = [] | n | 64 | self._candies = [] | 
| 63 | self.__visitors = [] | 65 | self._visitors = [] | ||
| 64 | for candy in candies: | 66 | for candy in candies: | ||
| n | 65 | self.__candies.append(Candy(*candy)) | n | 67 | self._candies.append(Candy(*candy)) | 
| 66 | 68 | ||||
| 67 | def remove_candy(self, pick_candy_func): | 69 | def remove_candy(self, pick_candy_func): | ||
| n | 68 | if len(self.__candies) != 0: | n | 70 | if not self._candies: | 
| 69 | candy = pick_candy_func(self.__candies) | ||||
| 70 | self.__candies.remove(candy) | ||||
| 71 | return candy | ||||
| 72 | else: | ||||
| 73 | return None | 71 | return None | ||
| n | n | 72 | candy = pick_candy_func(self._candies) | ||
| 73 | self._candies.remove(candy) | ||||
| 74 | return candy | ||||
| 74 | 75 | ||||
| 75 | def accept_visitor(self, kid): | 76 | def accept_visitor(self, kid): | ||
| n | 76 | self.__visitors.append(kid) | n | 77 | self._visitors.append(kid) | 
| 78 | |||||
| 79 | def get_compare_list(self, kid): | ||||
| 80 | return [ | ||||
| 81 | kid.distance_to(self), | ||||
| 82 | self._position[0], | ||||
| 83 | self._position[1], | ||||
| 84 | self | ||||
| 85 | ] | ||||
| 77 | 86 | ||||
| 78 | def give_out_candies(self, pick_candy_func): | 87 | def give_out_candies(self, pick_candy_func): | ||
| n | 79 | self.__visitors.sort(key=lambda kid: kid.get_initiative()) | n | 88 | self._visitors.sort(key=lambda kid: kid.get_initiative()) | 
| 80 | while len(self.__visitors) != 0: | 89 | while self._visitors: | ||
| 81 | kid = self.__visitors.pop() | 90 | kid = self._visitors.pop() | ||
| 82 | candy = self.remove_candy(pick_candy_func) | 91 | candy = self.remove_candy(pick_candy_func) | ||
| 83 | if candy is not None: | 92 | if candy is not None: | ||
| 84 | kid.add_candy(candy) | 93 | kid.add_candy(candy) | ||
| 85 | 94 | ||||
| 86 | 95 | ||||
| 87 | class FluxCapacitor: | 96 | class FluxCapacitor: | ||
| 88 | def __init__(self, participants): | 97 | def __init__(self, participants): | ||
| n | 89 | self.__kids = [] | n | 98 | self._kids = [] | 
| 90 | self.__hosts = [] | 99 | self._hosts = [] | ||
| 91 | self.__victims = [] | 100 | self._victims = set() | ||
| 92 | for participant in participants: | 101 | for participant in participants: | ||
| 93 | if type(participant) is Kid: | 102 | if type(participant) is Kid: | ||
| n | 94 | self.__kids.append(participant) | n | 103 | self._kids.append(participant) | 
| 95 | if type(participant) is Host: | 104 | if type(participant) is Host: | ||
| n | 96 | self.__hosts.append(participant) | n | 105 | self._hosts.append(participant) | 
| 97 | 106 | ||||
| n | 98 | def get_victims(self): | n | 107 | def get_victim(self): | 
| 99 | to_ignore = set() | 108 | kids_who_visited_all = set() | ||
| 100 | while (len(to_ignore) != len(self.__kids) | 109 | while (len(kids_who_visited_all) != len(self._kids) | ||
| 101 | and len(self.__victims) == 0): | 110 | and not self._victims): | ||
| 102 | for kid in self.__kids: | 111 | for kid in self._kids: | ||
| 103 | if kid in to_ignore: | 112 | if kid in kids_who_visited_all: | ||
| 104 | continue | 113 | continue | ||
| n | 105 | closest_host = self.__get_closest_host(kid) | n | 114 | closest_host = self._get_closest_host(kid) | 
| 106 | if closest_host is None: | 115 | if closest_host is None: | ||
| n | 107 | to_ignore.add(kid) | n | 116 | kids_who_visited_all.add(kid) | 
| 108 | continue | 117 | continue | ||
| 109 | kid.visit(closest_host) | 118 | kid.visit(closest_host) | ||
| 110 | closest_host.accept_visitor(kid) | 119 | closest_host.accept_visitor(kid) | ||
| n | 111 | for host in self.__hosts: | n | 120 | for host in self._hosts: | 
| 112 | host.give_out_candies(self.__pick_candy) | 121 | host.give_out_candies(self._pick_candy) | ||
| 113 | for kid in self.__kids: | 122 | for kid in self._kids: | ||
| 114 | if kid.is_critical(): | 123 | if kid.is_critical(): | ||
| n | 115 | self.__victims.append(kid) | n | 124 | self._victims.add(kid) | 
| 116 | if(len(self.__victims) != 0): | ||||
| 117 | return self.__victims | 125 | return self._victims or None | ||
| 118 | return None | ||||
| 119 | 126 | ||||
| n | 120 | def __get_closest_host(self, kid): | n | 127 | def _get_closest_host(self, kid): | 
| 121 | closest_host = None | 128 | closest_host = [None] | ||
| 122 | for host in self.__hosts: | 129 | for host in self._hosts: | ||
| 123 | if kid.has_visited(host): | 130 | if kid.has_visited(host): | ||
| 124 | continue | 131 | continue | ||
| n | 125 | if closest_host is None: | n | 132 | if None in closest_host: | 
| 126 | closest_host = host | 133 | closest_host = host.get_compare_list(kid) | ||
| 127 | continue | 134 | continue | ||
| n | 128 | if kid.distance_to(host) < kid.distance_to(closest_host): | n | 135 | closest_host = min(closest_host, host.get_compare_list(kid)) | 
| 129 | closest_host = host | ||||
| 130 | elif kid.distance_to(host) == kid.distance_to(closest_host): | ||||
| 131 | if host.get_position()[0] < closest_host.get_position()[0]: | ||||
| 132 | closest_host = host | ||||
| 133 | elif (host.get_position()[0] == closest_host.get_position()[0] | ||||
| 134 | and host.get_position()[1] < closest_host.get_position()[1]): | ||||
| 135 | closest_host = host | ||||
| 136 | return closest_host | 136 | return closest_host[-1] | ||
| 137 | 137 | ||||
| t | 138 | def __pick_candy(self, candies): | t | 138 | def _pick_candy(self, candies): | 
| 139 | return max(candies, key=(lambda candy: candy.get_mass())) | 139 | return max(candies, key=(lambda candy: candy.get_mass())) | 
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
 
  | 
              
  |  |||||||||