Домашни > Хелоуин в Припят > Решения > Решението на Светлозар Стефанов

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

10 точки общо

12 успешни теста
0 неуспешни теста
Код

  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
История

f1import mathf1import math
22
3class Candy:3class Candy:
4    def __init__(self, mass, uranium):4    def __init__(self, mass, uranium):
n5        self.__mass = massn5        self._mass = mass
6        self.__uranium = uranium6        self._uranium = uranium
77
8    def get_uranium_quantity(self):8    def get_uranium_quantity(self):
n9        return self.__mass * self.__uraniumn9        return self._mass * self._uranium
1010
11    def get_mass(self):11    def get_mass(self):
n12        return self.__massn12        return self._mass
1313
1414
15class Person:15class Person:
16    def __init__(self, position):16    def __init__(self, position):
17        self._position = position17        self._position = position
18    18    
19    def get_position(self):19    def get_position(self):
20        return self._position20        return self._position
21    21    
22    def set_position(self, position):22    def set_position(self, position):
23        self._position = position23        self._position = position
2424
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)
2828
2929
30class Kid(Person):30class Kid(Person):
nn31 
31    MAX_CANDIES = 2032    MAX_CANDIES = 20
3233
33    def __init__(self, position, initiative):34    def __init__(self, position, initiative):
34        super().__init__(position)35        super().__init__(position)
n35        self.__initiative = initiativen36        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 = 039        self._uranium_in_basket = 0
3940
40    def get_initiative(self):41    def get_initiative(self):
n41        return self.__initiativen42        return self._initiative
42    43    
43    def add_candy(self, candy):44    def add_candy(self, candy):
n44        self.__uranium_in_basket += candy.get_uranium_quantity()n45        self._uranium_in_basket += candy.get_uranium_quantity()
45        self.__candies.add(candy)46        self._candies.add(candy)
4647
47    def is_critical(self):48    def is_critical(self):
n48        if self.__uranium_in_basket > Kid.MAX_CANDIES:n49        if self._uranium_in_basket > self.MAX_CANDIES:
49            return True50            return True
50        return False51        return False
51    52    
52    def visit(self, host):53    def visit(self, host):
n53        self.__visited_hosts.add(host)n54        self._visited_hosts.add(host)
55        self.set_position(host.get_position())
5456
55    def has_visited(self, host):57    def has_visited(self, host):
n56        return host in self.__visited_hostsn58        return host in self._visited_hosts
57    59    
5860
59class Host(Person):61class Host(Person):
60    def __init__(self, position, candies):62    def __init__(self, position, candies):
61        super().__init__(position)63        super().__init__(position)
n62        self.__candies = []n64        self._candies = []
63        self.__visitors = []65        self._visitors = []
64        for candy in candies:66        for candy in candies:
n65            self.__candies.append(Candy(*candy))n67            self._candies.append(Candy(*candy))
6668
67    def remove_candy(self, pick_candy_func):69    def remove_candy(self, pick_candy_func):
n68        if len(self.__candies) != 0:n70        if not self._candies:
69            candy = pick_candy_func(self.__candies)
70            self.__candies.remove(candy)
71            return candy
72        else:
73            return None71            return None
nn72        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):
n76        self.__visitors.append(kid)n77        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        ]
7786
78    def give_out_candies(self, pick_candy_func):87    def give_out_candies(self, pick_candy_func):
n79        self.__visitors.sort(key=lambda kid: kid.get_initiative())n88        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)
8594
86        95        
87class FluxCapacitor:96class FluxCapacitor:
88    def __init__(self, participants):97    def __init__(self, participants):
n89        self.__kids = []n98        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:
n94                self.__kids.append(participant)n103                self._kids.append(participant)
95            if type(participant) is Host:104            if type(participant) is Host:
n96                self.__hosts.append(participant)n105                self._hosts.append(participant)
97106
n98    def get_victims(self):n107    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                    continue113                    continue
n105                closest_host = self.__get_closest_host(kid)n114                closest_host = self._get_closest_host(kid)
106                if closest_host is None:115                if closest_host is None:
n107                    to_ignore.add(kid)n116                    kids_who_visited_all.add(kid)
108                    continue117                    continue
109                kid.visit(closest_host)118                kid.visit(closest_host)
110                closest_host.accept_visitor(kid)119                closest_host.accept_visitor(kid)
n111            for host in self.__hosts:n120            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():
n115                    self.__victims.append(kid)n124                    self._victims.add(kid)
116        if(len(self.__victims) != 0):
117            return self.__victims125        return self._victims or None
118        return None
119    126    
n120    def __get_closest_host(self, kid):n127    def _get_closest_host(self, kid):
121        closest_host = None128        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                continue131                continue
n125            if closest_host is None:n132            if None in closest_host:
126                closest_host = host133                closest_host = host.get_compare_list(kid)
127                continue134                continue
n128            if kid.distance_to(host) < kid.distance_to(closest_host):n135            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_host136        return closest_host[-1]
137    137    
t138    def __pick_candy(self, candies):t138    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
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op