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

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

10 точки общо

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

  1import math
  2
  3
  4class Candy:
  5
  6    def __init__(self, mass, uranium):
  7        """Initializer."""
  8        self._mass = mass
  9        self._uranium = uranium
 10
 11    def get_uranium_quantity(self):
 12        """Calculate and return the quantity of uranium in grams."""
 13        return self._mass * self._uranium
 14
 15    def get_mass(self):
 16        """Return the mass of the candy."""
 17        return self._mass
 18
 19
 20class Person:
 21
 22    def __init__(self, position):
 23        """Initializer."""
 24        self._position = position
 25
 26    def get_position(self):
 27        """Return the position (coordinates) of the person."""
 28        return self._position
 29
 30    def set_position(self, new_position):
 31        """Change the position to the new coordinates: new_position."""
 32        self._position = new_position
 33
 34
 35class Kid(Person):
 36
 37    CRITICAL_RADIATION = 20
 38
 39    def __init__(self, position, initiative):
 40        """Initializer."""
 41        super().__init__(position)
 42        self._initiative = initiative
 43        self._current_radiation = 0
 44        self._candy_bag = []
 45        self.visited_hosts = []
 46
 47    def get_initiative(self):
 48        """Return the value of the initiative."""
 49        return self._initiative
 50
 51    def add_candy(self, candy):
 52        """Get Candy object instance and add its radiation to the total current radiation sum."""
 53        self._current_radiation += candy.get_uranium_quantity()
 54        self._candy_bag.append(candy)
 55
 56    def is_critical(self):
 57        """Return bool value of whether the accumulated candy radiation has reached critical amounts."""
 58        return self._current_radiation > self.CRITICAL_RADIATION
 59
 60
 61class Host(Person):
 62
 63    def __init__(self, position, candies):
 64        """Initializer."""
 65        super().__init__(position)
 66        self.candy_bag = [Candy(*candy) for candy in candies]
 67        self.sort_candy_bag_based_on_mass()
 68
 69    def sort_candy_bag_based_on_mass(self):
 70        """Sort the candy bag so that candies go from the lowest mass to the highest mass."""
 71        self.candy_bag.sort(key=lambda candy: candy.get_mass())
 72
 73    def remove_candy(self, choose_candy_to_give):
 74        """Remove a candy from the candy bag. Which one is determined by the passed argument - function."""
 75        if self.candy_bag:
 76            candy_to_remove = choose_candy_to_give(self.candy_bag)
 77            self.candy_bag.remove(candy_to_remove)
 78            return candy_to_remove
 79        return None
 80
 81
 82class FluxCapacitor:
 83
 84    def __init__(self, participants):
 85        """Initializer."""
 86        self._participants = participants
 87        self._victims = set()
 88        self._kids = self._get_kids()
 89        self._hosts = self._get_hosts()
 90
 91    def _get_kids(self):
 92        """Return set of kids."""
 93        return {kid for kid in self._participants if isinstance(kid, Kid)}
 94
 95    def _get_hosts(self):
 96        """Return set of hosts."""
 97        return {host for host in self._participants if isinstance(host, Host)}
 98
 99    def _get_next_host_to_visit(self, kid):
100        """Find the next host for each left kid to visit based on shortest distance."""
101        list_distances_hosts = []
102        for curr_host in self._hosts:
103            if curr_host not in kid.visited_hosts:
104                curr_dist = math.dist(kid.get_position(), curr_host.get_position())
105                dist_x_y = (curr_dist, curr_host.get_position()[0], curr_host.get_position()[1], curr_host)
106                list_distances_hosts.append(dist_x_y)
107
108        list_distances_hosts.sort()
109        return list_distances_hosts[0][-1]
110
111    def _get_kids_that_will_visit(self, host):
112        """Get list of kids that will visit the current host. Sort list based on initiative."""
113        if self._kids:
114            kids_to_visit = []
115            for kid in self._kids:
116                if kid not in self._victims:
117                    if self._get_next_host_to_visit(kid) is host:
118                        kids_to_visit.append(kid)
119            kids_to_visit.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
120            return kids_to_visit
121        return None
122
123    @staticmethod
124    def choose_candy_from_host(candy_bag):
125        """Get the chunkiest candy from the host's bag. Candies in the bag are previously sorted by mass."""
126        return candy_bag[-1]
127
128    def _give_poisonous_candy(self, host):
129        """Attempt to give poisonous candy to the innocent children. If any kid dies, add it to the pile of victims."""
130        if self._get_kids_that_will_visit(host):
131            visitation_happened = False
132            for kid in self._get_kids_that_will_visit(host):
133                if host.candy_bag:
134                    visitation_happened = True
135                    candy_to_be_given = host.remove_candy(self.choose_candy_from_host)
136                    kid.add_candy(candy_to_be_given)
137                    kid.visited_hosts.append(host)
138                    kid.set_position(host.get_position())
139                    if kid.is_critical():
140                        self._victims.add(kid)
141            return visitation_happened
142        return False
143
144    def get_victim(self):
145        """Iterate visitations to distribute the candy. Return set of the first victims or None if all survived."""
146        happy_ending = False
147        while not self._victims and not happy_ending:
148            happy_ending = True
149            for host in self._hosts:
150                if self._give_poisonous_candy(host):
151                    # No happy ending until all the candy has been given
152                    happy_ending = False
153        return None if happy_ending else self._victims

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

OK

Дискусия
История

f1import mathf1import math
n2 n
3BIG_NUM = 100000
4 
5 
6def choose_candy_from_host(candy_bag):
7    """Get the chunkiest candy from the host's bag. Candies in the bag are previously sorted by mass."""
8    return candy_bag[-1]
92
103
11class Candy:4class Candy:
nn5 
12    def __init__(self, mass, uranium):6    def __init__(self, mass, uranium):
n13        """Constructor."""n7        """Initializer."""
14        self._mass = mass8        self._mass = mass
15        self._uranium = uranium9        self._uranium = uranium
1610
17    def get_uranium_quantity(self):11    def get_uranium_quantity(self):
18        """Calculate and return the quantity of uranium in grams."""12        """Calculate and return the quantity of uranium in grams."""
19        return self._mass * self._uranium13        return self._mass * self._uranium
2014
21    def get_mass(self):15    def get_mass(self):
22        """Return the mass of the candy."""16        """Return the mass of the candy."""
23        return self._mass17        return self._mass
2418
2519
26class Person:20class Person:
nn21 
27    def __init__(self, position):22    def __init__(self, position):
n28        """Constructor."""n23        """Initializer."""
29        self._position = position24        self._position = position
3025
31    def get_position(self):26    def get_position(self):
n32        """Return the position (coordinates) of the person as (x, y) tuple."""n27        """Return the position (coordinates) of the person."""
33        return self._position28        return self._position
3429
35    def set_position(self, new_position):30    def set_position(self, new_position):
36        """Change the position to the new coordinates: new_position."""31        """Change the position to the new coordinates: new_position."""
37        self._position = new_position32        self._position = new_position
3833
3934
40class Kid(Person):35class Kid(Person):
nn36 
37    CRITICAL_RADIATION = 20
38 
41    def __init__(self, position, initiative):39    def __init__(self, position, initiative):
n42        """Constructor."""n40        """Initializer."""
43        super().__init__(position)41        super().__init__(position)
44        self._initiative = initiative42        self._initiative = initiative
45        self._current_radiation = 043        self._current_radiation = 0
n46        self._critical_radiation = 20n44        self._candy_bag = []
47        self.visited_hosts = []45        self.visited_hosts = []
4846
49    def get_initiative(self):47    def get_initiative(self):
50        """Return the value of the initiative."""48        """Return the value of the initiative."""
51        return self._initiative49        return self._initiative
5250
53    def add_candy(self, candy):51    def add_candy(self, candy):
54        """Get Candy object instance and add its radiation to the total current radiation sum."""52        """Get Candy object instance and add its radiation to the total current radiation sum."""
55        self._current_radiation += candy.get_uranium_quantity()53        self._current_radiation += candy.get_uranium_quantity()
nn54        self._candy_bag.append(candy)
5655
57    def is_critical(self):56    def is_critical(self):
58        """Return bool value of whether the accumulated candy radiation has reached critical amounts."""57        """Return bool value of whether the accumulated candy radiation has reached critical amounts."""
n59        return self._current_radiation > self._critical_radiationn58        return self._current_radiation > self.CRITICAL_RADIATION
6059
6160
62class Host(Person):61class Host(Person):
nn62 
63    def __init__(self, position, candies):63    def __init__(self, position, candies):
n64        """Constructor."""n64        """Initializer."""
65        super().__init__(position)65        super().__init__(position)
n66        self.candy_bag = [Candy(candy[0], candy[1]) for candy in candies]n66        self.candy_bag = [Candy(*candy) for candy in candies]
67        self.sort_candy_bag_based_on_mass()67        self.sort_candy_bag_based_on_mass()
6868
69    def sort_candy_bag_based_on_mass(self):69    def sort_candy_bag_based_on_mass(self):
70        """Sort the candy bag so that candies go from the lowest mass to the highest mass."""70        """Sort the candy bag so that candies go from the lowest mass to the highest mass."""
71        self.candy_bag.sort(key=lambda candy: candy.get_mass())71        self.candy_bag.sort(key=lambda candy: candy.get_mass())
7272
73    def remove_candy(self, choose_candy_to_give):73    def remove_candy(self, choose_candy_to_give):
74        """Remove a candy from the candy bag. Which one is determined by the passed argument - function."""74        """Remove a candy from the candy bag. Which one is determined by the passed argument - function."""
75        if self.candy_bag:75        if self.candy_bag:
76            candy_to_remove = choose_candy_to_give(self.candy_bag)76            candy_to_remove = choose_candy_to_give(self.candy_bag)
n77            if candy_to_remove in self.candy_bag:n
78                self.candy_bag.remove(candy_to_remove)77            self.candy_bag.remove(candy_to_remove)
79            return candy_to_remove78            return candy_to_remove
80        return None79        return None
8180
8281
83class FluxCapacitor:82class FluxCapacitor:
nn83 
84    def __init__(self, participants):84    def __init__(self, participants):
n85        """Constructor."""n85        """Initializer."""
86        self._participants = participants86        self._participants = participants
87        self._victims = set()87        self._victims = set()
88        self._kids = self._get_kids()88        self._kids = self._get_kids()
89        self._hosts = self._get_hosts()89        self._hosts = self._get_hosts()
9090
91    def _get_kids(self):91    def _get_kids(self):
92        """Return set of kids."""92        """Return set of kids."""
93        return {kid for kid in self._participants if isinstance(kid, Kid)}93        return {kid for kid in self._participants if isinstance(kid, Kid)}
9494
95    def _get_hosts(self):95    def _get_hosts(self):
96        """Return set of hosts."""96        """Return set of hosts."""
97        return {host for host in self._participants if isinstance(host, Host)}97        return {host for host in self._participants if isinstance(host, Host)}
9898
n99    @staticmethodn
100    def _is_closer(last_closest_host, curr_host, kid):
101        """Return bool if the current host is closer to the current child than the last host."""
102        curr_dist = math.dist(kid.get_position(), curr_host.get_position())
103        last_shortest = math.dist(last_closest_host.get_position(), kid.get_position()) if last_closest_host else BIG_NUM
104 
105        if curr_dist < last_shortest:
106            return True
107        if math.isclose(curr_dist, last_shortest):
108            if curr_host.get_position()[0] < last_closest_host.get_position()[0]:
109                return True
110            elif (math.isclose(curr_host.get_position()[0], last_closest_host.get_position()[0]) and
111                  curr_host.get_position()[1] < last_closest_host.get_position()[1]):
112                return True
113        return False
114 
115    def _get_next_host_to_visit(self, kid):99    def _get_next_host_to_visit(self, kid):
116        """Find the next host for each left kid to visit based on shortest distance."""100        """Find the next host for each left kid to visit based on shortest distance."""
n117        last_closest_host = Nonen101        list_distances_hosts = []
118        for curr_host in self._hosts:102        for curr_host in self._hosts:
119            if curr_host not in kid.visited_hosts:103            if curr_host not in kid.visited_hosts:
n120                if self._is_closer(last_closest_host, curr_host, kid):n104                curr_dist = math.dist(kid.get_position(), curr_host.get_position())
121                    last_closest_host = curr_host105                dist_x_y = (curr_dist, curr_host.get_position()[0], curr_host.get_position()[1], curr_host)
122        return last_closest_host106                list_distances_hosts.append(dist_x_y)
107 
108        list_distances_hosts.sort()
109        return list_distances_hosts[0][-1]
123110
124    def _get_kids_that_will_visit(self, host):111    def _get_kids_that_will_visit(self, host):
125        """Get list of kids that will visit the current host. Sort list based on initiative."""112        """Get list of kids that will visit the current host. Sort list based on initiative."""
126        if self._kids:113        if self._kids:
127            kids_to_visit = []114            kids_to_visit = []
128            for kid in self._kids:115            for kid in self._kids:
129                if kid not in self._victims:116                if kid not in self._victims:
n130                    if self._get_next_host_to_visit(kid) == host:n117                    if self._get_next_host_to_visit(kid) is host:
131                        kids_to_visit.append(kid)118                        kids_to_visit.append(kid)
132            kids_to_visit.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)119            kids_to_visit.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
133            return kids_to_visit120            return kids_to_visit
134        return None121        return None
nn122 
123    @staticmethod
124    def choose_candy_from_host(candy_bag):
125        """Get the chunkiest candy from the host's bag. Candies in the bag are previously sorted by mass."""
126        return candy_bag[-1]
135127
136    def _give_poisonous_candy(self, host):128    def _give_poisonous_candy(self, host):
137        """Attempt to give poisonous candy to the innocent children. If any kid dies, add it to the pile of victims."""129        """Attempt to give poisonous candy to the innocent children. If any kid dies, add it to the pile of victims."""
138        if self._get_kids_that_will_visit(host):130        if self._get_kids_that_will_visit(host):
139            visitation_happened = False131            visitation_happened = False
140            for kid in self._get_kids_that_will_visit(host):132            for kid in self._get_kids_that_will_visit(host):
141                if host.candy_bag:133                if host.candy_bag:
142                    visitation_happened = True134                    visitation_happened = True
t143                    candy_to_be_given = host.remove_candy(choose_candy_from_host)t135                    candy_to_be_given = host.remove_candy(self.choose_candy_from_host)
144                    kid.add_candy(candy_to_be_given)136                    kid.add_candy(candy_to_be_given)
145                    kid.visited_hosts.append(host)137                    kid.visited_hosts.append(host)
146                    kid.set_position(host.get_position())138                    kid.set_position(host.get_position())
147                    if kid.is_critical():139                    if kid.is_critical():
148                        self._victims.add(kid)140                        self._victims.add(kid)
149            return visitation_happened141            return visitation_happened
150        return False142        return False
151143
152    def get_victim(self):144    def get_victim(self):
153        """Iterate visitations to distribute the candy. Return set of the first victims or None if all survived."""145        """Iterate visitations to distribute the candy. Return set of the first victims or None if all survived."""
154        happy_ending = False146        happy_ending = False
155        while not self._victims and not happy_ending:147        while not self._victims and not happy_ending:
156            happy_ending = True148            happy_ending = True
157            for host in self._hosts:149            for host in self._hosts:
158                if self._give_poisonous_candy(host):150                if self._give_poisonous_candy(host):
159                    # No happy ending until all the candy has been given151                    # No happy ending until all the candy has been given
160                    happy_ending = False152                    happy_ending = False
161        return None if happy_ending else self._victims153        return None if happy_ending else self._victims
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op