Домашни > Хелоуин в Припят > Решения > Решението на Рая Григорова

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

10 точки общо

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

  1import math
  2
  3
  4class Candy:
  5
  6    def __init__(self, mass, uranium):
  7        self.mass = mass
  8        self.uranium = uranium
  9
 10    def get_uranium_quantity(self):
 11        """Return the quantity of uranium in grams."""
 12        return self.mass * self.uranium
 13
 14    def get_mass(self):
 15        return self.mass
 16
 17
 18class Person:
 19
 20    def __init__(self, position):
 21        self.position = position
 22
 23    def get_position(self):
 24        return self.position
 25
 26    def set_position(self, position):
 27        self.position = position
 28
 29    @staticmethod
 30    def get_distance(person_1, person_2):
 31        """Calculate the distance between two people."""
 32        dx = person_1.position[0] - person_2.position[0]
 33        dy = person_1.position[1] - person_2.position[1]
 34        return math.sqrt(dx ** 2 + dy ** 2)
 35
 36
 37class Kid(Person):
 38
 39    CRITICAL_MASS = 20
 40
 41    def __init__(self, position, initiative):
 42        super().__init__(position)
 43        self.initiative = initiative
 44        self.basket = list()
 45
 46    def get_initiative(self):
 47        return self.initiative
 48
 49    def add_candy(self, candy_to_add):
 50        self.basket.append(candy_to_add)
 51
 52    def is_critical(self):
 53        """Sum the uranium contents of all candies and returns true if sum > 20."""
 54        uranium_sum = sum(candy.get_uranium_quantity() for candy in self.basket)
 55        return uranium_sum > Kid.CRITICAL_MASS
 56
 57
 58class Host(Person):
 59
 60    def __init__(self, position, candies):
 61        super().__init__(position)
 62        self.candies = [Candy(x, y) for x, y in candies]
 63        self.visited_from = []  # add children that already visited a given host here
 64        self.current_visitors = []  # add children that are visiting the host at the moment
 65
 66    def remove_candy(self, func_remove_candy):
 67        # if the host doesn't have candy, do nothing
 68        if not self.candies:
 69            return None
 70        # save the candy to delete from the list
 71        candy_to_remove = func_remove_candy(self.candies)
 72        self.candies.remove(candy_to_remove)
 73        return candy_to_remove
 74
 75
 76class FluxCapacitor:
 77
 78    def __init__(self, participants):
 79        self.kids = [person for person in participants if type(person) == Kid]
 80        self.hosts = [person for person in participants if type(person) == Host]
 81
 82    @staticmethod
 83    def find_candy_with_biggest_mass(candies):
 84        return max(candies, key=lambda some_candy: some_candy.mass)
 85
 86    def get_victim(self):
 87        while True:
 88            all_kids_visited_all_hosts = all(len(host.visited_from) == len(self.kids) for host in self.hosts)
 89            if all_kids_visited_all_hosts:
 90                break
 91
 92            # first, determine for each kid which house it's going to visit
 93            for kid in self.kids:
 94                try:
 95                    closest_unvisited_house = min([host for host in self.hosts if kid not in host.visited_from],
 96                                                  key=lambda host: (
 97                                                      Person.get_distance(kid, host), host.position[0],
 98                                                      host.position[1]))
 99                # ValueError will be thrown if the iterable is empty (there are no unvisited hosts for the current kid)
100                except ValueError:
101                    continue
102
103                # mark closest_unvisited_house as being actively visited by the respective kid
104                closest_unvisited_house.current_visitors.append(kid)
105                # the kid moves to the closest house, so change its coordinates
106                kid.set_position(closest_unvisited_house.position)
107
108            # secondly, make the hosts distribute the candy
109            for host in self.hosts:
110                while host.current_visitors:  # aim to empty the active visitors list
111                    # if the host doesn't have candy, remove all current visitors
112                    # and add them to the list of past visitors
113                    if not host.candies:
114                        host.visited_from += host.current_visitors
115                        host.current_visitors = []
116                        break
117
118                    # determine the next kid by comparing initiatives
119                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)
120                    # find candy for the next kid
121                    next_candy = host.remove_candy(FluxCapacitor.find_candy_with_biggest_mass)
122                    # add candy to kid's basket
123                    next_kid.add_candy(next_candy)
124                    # save the kid in the list of past visitors and remove it from active visitors
125                    host.visited_from.append(next_kid)
126                    host.current_visitors.remove(next_kid)
127
128            # the last step is to add all children that have received critical mass to a set
129            irridated_kids = set()
130            for kid in self.kids:
131                if kid.is_critical():
132                    irridated_kids.add(kid)
133            if irridated_kids:
134                return irridated_kids
135
136        return None

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

OK

Дискусия
Георги Кунчев
03.11.2023 14:49

Сега е ок. Няма безкраен цикъл.
Георги Кунчев
03.11.2023 11:29

При тестване се получава безкраен цикъл. Моля изтествай си решението за `FluxCapacitor` с някакъв реален случай.
История

f1import mathf1import math
22
33
4class Candy:4class Candy:
55
6    def __init__(self, mass, uranium):6    def __init__(self, mass, uranium):
7        self.mass = mass7        self.mass = mass
8        self.uranium = uranium8        self.uranium = uranium
99
10    def get_uranium_quantity(self):10    def get_uranium_quantity(self):
11        """Return the quantity of uranium in grams."""11        """Return the quantity of uranium in grams."""
12        return self.mass * self.uranium12        return self.mass * self.uranium
1313
14    def get_mass(self):14    def get_mass(self):
15        return self.mass15        return self.mass
1616
1717
18class Person:18class Person:
1919
20    def __init__(self, position):20    def __init__(self, position):
21        self.position = position21        self.position = position
2222
23    def get_position(self):23    def get_position(self):
24        return self.position24        return self.position
2525
26    def set_position(self, position):26    def set_position(self, position):
27        self.position = position27        self.position = position
2828
29    @staticmethod29    @staticmethod
30    def get_distance(person_1, person_2):30    def get_distance(person_1, person_2):
31        """Calculate the distance between two people."""31        """Calculate the distance between two people."""
32        dx = person_1.position[0] - person_2.position[0]32        dx = person_1.position[0] - person_2.position[0]
33        dy = person_1.position[1] - person_2.position[1]33        dy = person_1.position[1] - person_2.position[1]
34        return math.sqrt(dx ** 2 + dy ** 2)34        return math.sqrt(dx ** 2 + dy ** 2)
3535
3636
37class Kid(Person):37class Kid(Person):
3838
39    CRITICAL_MASS = 2039    CRITICAL_MASS = 20
4040
41    def __init__(self, position, initiative):41    def __init__(self, position, initiative):
42        super().__init__(position)42        super().__init__(position)
43        self.initiative = initiative43        self.initiative = initiative
44        self.basket = list()44        self.basket = list()
4545
46    def get_initiative(self):46    def get_initiative(self):
47        return self.initiative47        return self.initiative
4848
49    def add_candy(self, candy_to_add):49    def add_candy(self, candy_to_add):
50        self.basket.append(candy_to_add)50        self.basket.append(candy_to_add)
5151
52    def is_critical(self):52    def is_critical(self):
53        """Sum the uranium contents of all candies and returns true if sum > 20."""53        """Sum the uranium contents of all candies and returns true if sum > 20."""
54        uranium_sum = sum(candy.get_uranium_quantity() for candy in self.basket)54        uranium_sum = sum(candy.get_uranium_quantity() for candy in self.basket)
55        return uranium_sum > Kid.CRITICAL_MASS55        return uranium_sum > Kid.CRITICAL_MASS
5656
5757
58class Host(Person):58class Host(Person):
5959
60    def __init__(self, position, candies):60    def __init__(self, position, candies):
61        super().__init__(position)61        super().__init__(position)
62        self.candies = [Candy(x, y) for x, y in candies]62        self.candies = [Candy(x, y) for x, y in candies]
63        self.visited_from = []  # add children that already visited a given host here63        self.visited_from = []  # add children that already visited a given host here
64        self.current_visitors = []  # add children that are visiting the host at the moment64        self.current_visitors = []  # add children that are visiting the host at the moment
6565
66    def remove_candy(self, func_remove_candy):66    def remove_candy(self, func_remove_candy):
67        # if the host doesn't have candy, do nothing67        # if the host doesn't have candy, do nothing
68        if not self.candies:68        if not self.candies:
69            return None69            return None
70        # save the candy to delete from the list70        # save the candy to delete from the list
71        candy_to_remove = func_remove_candy(self.candies)71        candy_to_remove = func_remove_candy(self.candies)
72        self.candies.remove(candy_to_remove)72        self.candies.remove(candy_to_remove)
73        return candy_to_remove73        return candy_to_remove
7474
7575
76class FluxCapacitor:76class FluxCapacitor:
7777
78    def __init__(self, participants):78    def __init__(self, participants):
79        self.kids = [person for person in participants if type(person) == Kid]79        self.kids = [person for person in participants if type(person) == Kid]
80        self.hosts = [person for person in participants if type(person) == Host]80        self.hosts = [person for person in participants if type(person) == Host]
8181
82    @staticmethod82    @staticmethod
83    def find_candy_with_biggest_mass(candies):83    def find_candy_with_biggest_mass(candies):
84        return max(candies, key=lambda some_candy: some_candy.mass)84        return max(candies, key=lambda some_candy: some_candy.mass)
8585
86    def get_victim(self):86    def get_victim(self):
87        while True:87        while True:
88            all_kids_visited_all_hosts = all(len(host.visited_from) == len(self.kids) for host in self.hosts)88            all_kids_visited_all_hosts = all(len(host.visited_from) == len(self.kids) for host in self.hosts)
89            if all_kids_visited_all_hosts:89            if all_kids_visited_all_hosts:
90                break90                break
9191
92            # first, determine for each kid which house it's going to visit92            # first, determine for each kid which house it's going to visit
93            for kid in self.kids:93            for kid in self.kids:
94                try:94                try:
95                    closest_unvisited_house = min([host for host in self.hosts if kid not in host.visited_from],95                    closest_unvisited_house = min([host for host in self.hosts if kid not in host.visited_from],
96                                                  key=lambda host: (96                                                  key=lambda host: (
97                                                      Person.get_distance(kid, host), host.position[0],97                                                      Person.get_distance(kid, host), host.position[0],
98                                                      host.position[1]))98                                                      host.position[1]))
n99                # ValueError will be thrown if the iterable is empty (there are no unvisited self.hosts for the current kid)n99                # ValueError will be thrown if the iterable is empty (there are no unvisited hosts for the current kid)
100                except ValueError:100                except ValueError:
101                    continue101                    continue
102102
n103                # mark the closest_unvisited_house as being actively visited by the respective kidn103                # mark closest_unvisited_house as being actively visited by the respective kid
104                closest_unvisited_house.current_visitors.append(kid)104                closest_unvisited_house.current_visitors.append(kid)
105                # the kid moves to the closest house, so change its coordinates105                # the kid moves to the closest house, so change its coordinates
106                kid.set_position(closest_unvisited_house.position)106                kid.set_position(closest_unvisited_house.position)
107107
t108            # secondly, make the self.hosts distribute the candyt108            # secondly, make the hosts distribute the candy
109            for host in self.hosts:109            for host in self.hosts:
110                while host.current_visitors:  # aim to empty the active visitors list110                while host.current_visitors:  # aim to empty the active visitors list
111                    # if the host doesn't have candy, remove all current visitors111                    # if the host doesn't have candy, remove all current visitors
112                    # and add them to the list of past visitors112                    # and add them to the list of past visitors
113                    if not host.candies:113                    if not host.candies:
114                        host.visited_from += host.current_visitors114                        host.visited_from += host.current_visitors
115                        host.current_visitors = []115                        host.current_visitors = []
116                        break116                        break
117117
118                    # determine the next kid by comparing initiatives118                    # determine the next kid by comparing initiatives
119                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)119                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)
120                    # find candy for the next kid120                    # find candy for the next kid
121                    next_candy = host.remove_candy(FluxCapacitor.find_candy_with_biggest_mass)121                    next_candy = host.remove_candy(FluxCapacitor.find_candy_with_biggest_mass)
122                    # add candy to kid's basket122                    # add candy to kid's basket
123                    next_kid.add_candy(next_candy)123                    next_kid.add_candy(next_candy)
124                    # save the kid in the list of past visitors and remove it from active visitors124                    # save the kid in the list of past visitors and remove it from active visitors
125                    host.visited_from.append(next_kid)125                    host.visited_from.append(next_kid)
126                    host.current_visitors.remove(next_kid)126                    host.current_visitors.remove(next_kid)
127127
128            # the last step is to add all children that have received critical mass to a set128            # the last step is to add all children that have received critical mass to a set
129            irridated_kids = set()129            irridated_kids = set()
130            for kid in self.kids:130            for kid in self.kids:
131                if kid.is_critical():131                if kid.is_critical():
132                    irridated_kids.add(kid)132                    irridated_kids.add(kid)
133            if irridated_kids:133            if irridated_kids:
134                return irridated_kids134                return irridated_kids
135135
136        return None136        return None
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
22
33
4class Candy:4class Candy:
nn5 
5    def __init__(self, mass, uranium):6    def __init__(self, mass, uranium):
6        self.mass = mass7        self.mass = mass
7        self.uranium = uranium8        self.uranium = uranium
89
9    def get_uranium_quantity(self):10    def get_uranium_quantity(self):
10        """Return the quantity of uranium in grams."""11        """Return the quantity of uranium in grams."""
11        return self.mass * self.uranium12        return self.mass * self.uranium
1213
13    def get_mass(self):14    def get_mass(self):
14        return self.mass15        return self.mass
1516
1617
17class Person:18class Person:
nn19 
18    def __init__(self, position):20    def __init__(self, position):
19        self.position = position21        self.position = position
2022
21    def get_position(self):23    def get_position(self):
22        return self.position24        return self.position
2325
24    def set_position(self, position):26    def set_position(self, position):
25        self.position = position27        self.position = position
2628
27    @staticmethod29    @staticmethod
28    def get_distance(person_1, person_2):30    def get_distance(person_1, person_2):
n29        """This function calculates the distance between two people."""n31        """Calculate the distance between two people."""
30        dx = person_1.position[0] - person_2.position[0]32        dx = person_1.position[0] - person_2.position[0]
31        dy = person_1.position[1] - person_2.position[1]33        dy = person_1.position[1] - person_2.position[1]
32        return math.sqrt(dx ** 2 + dy ** 2)34        return math.sqrt(dx ** 2 + dy ** 2)
3335
3436
35class Kid(Person):37class Kid(Person):
nn38 
39    CRITICAL_MASS = 20
40 
36    def __init__(self, position, initiative):41    def __init__(self, position, initiative):
37        super().__init__(position)42        super().__init__(position)
38        self.initiative = initiative43        self.initiative = initiative
39        self.basket = list()44        self.basket = list()
4045
41    def get_initiative(self):46    def get_initiative(self):
42        return self.initiative47        return self.initiative
4348
44    def add_candy(self, candy_to_add):49    def add_candy(self, candy_to_add):
45        self.basket.append(candy_to_add)50        self.basket.append(candy_to_add)
4651
47    def is_critical(self):52    def is_critical(self):
n48        """This function sums the uranium contents of all candies and returns true if sum > 20."""n53        """Sum the uranium contents of all candies and returns true if sum > 20."""
49        uranium_sum = 0.054        uranium_sum = sum(candy.get_uranium_quantity() for candy in self.basket)
50        for candy in self.basket:
51            uranium_sum += candy.get_uranium_quantity()
52        return uranium_sum > 2055        return uranium_sum > Kid.CRITICAL_MASS
5356
5457
55class Host(Person):58class Host(Person):
nn59 
56    def __init__(self, position, candies):60    def __init__(self, position, candies):
57        super().__init__(position)61        super().__init__(position)
58        self.candies = [Candy(x, y) for x, y in candies]62        self.candies = [Candy(x, y) for x, y in candies]
59        self.visited_from = []  # add children that already visited a given host here63        self.visited_from = []  # add children that already visited a given host here
60        self.current_visitors = []  # add children that are visiting the host at the moment64        self.current_visitors = []  # add children that are visiting the host at the moment
6165
62    def remove_candy(self, func_remove_candy):66    def remove_candy(self, func_remove_candy):
63        # if the host doesn't have candy, do nothing67        # if the host doesn't have candy, do nothing
64        if not self.candies:68        if not self.candies:
65            return None69            return None
66        # save the candy to delete from the list70        # save the candy to delete from the list
67        candy_to_remove = func_remove_candy(self.candies)71        candy_to_remove = func_remove_candy(self.candies)
68        self.candies.remove(candy_to_remove)72        self.candies.remove(candy_to_remove)
69        return candy_to_remove73        return candy_to_remove
7074
7175
n72def find_candy_with_biggest_mass(candies):n76class FluxCapacitor:
73    return max(candies, key=lambda some_candy: some_candy.mass)
7477
nn78    def __init__(self, participants):
79        self.kids = [person for person in participants if type(person) == Kid]
80        self.hosts = [person for person in participants if type(person) == Host]
7581
n76class FluxCapacitor:n82    @staticmethod
77    def __init__(self, participants):83    def find_candy_with_biggest_mass(candies):
78        self.participants = participants84        return max(candies, key=lambda some_candy: some_candy.mass)
7985
80    def get_victim(self):86    def get_victim(self):
n81        kids = [person for person in self.participants if type(person) == Kid]n
82        hosts = [person for person in self.participants if type(person) == Host]
83 
84        while True:87        while True:
n85            all_kids_visited_all_hosts = all(len(host.visited_from) == len(kids) for host in hosts)n88            all_kids_visited_all_hosts = all(len(host.visited_from) == len(self.kids) for host in self.hosts)
86            if all_kids_visited_all_hosts:89            if all_kids_visited_all_hosts:
87                break90                break
8891
89            # first, determine for each kid which house it's going to visit92            # first, determine for each kid which house it's going to visit
n90            for kid in kids:n93            for kid in self.kids:
91                try:94                try:
n92                    closest_unvisited_house = min([host for host in hosts if kid not in host.visited_from],n95                    closest_unvisited_house = min([host for host in self.hosts if kid not in host.visited_from],
93                                                  key=lambda host: (96                                                  key=lambda host: (
94                                                      Person.get_distance(kid, host), host.position[0],97                                                      Person.get_distance(kid, host), host.position[0],
95                                                      host.position[1]))98                                                      host.position[1]))
n96                # ValueError will be thrown if the iterable is empty (there are no unvisited hosts for the current kid)n99                # ValueError will be thrown if the iterable is empty (there are no unvisited self.hosts for the current kid)
97                except ValueError:100                except ValueError:
n98                    breakn101                    continue
99102
100                # mark the closest_unvisited_house as being actively visited by the respective kid103                # mark the closest_unvisited_house as being actively visited by the respective kid
101                closest_unvisited_house.current_visitors.append(kid)104                closest_unvisited_house.current_visitors.append(kid)
102                # the kid moves to the closest house, so change its coordinates105                # the kid moves to the closest house, so change its coordinates
103                kid.set_position(closest_unvisited_house.position)106                kid.set_position(closest_unvisited_house.position)
104107
n105            # secondly, make the hosts distribute the candyn108            # secondly, make the self.hosts distribute the candy
106            for host in hosts:109            for host in self.hosts:
107                while host.current_visitors:  # aim to empty the active visitors list110                while host.current_visitors:  # aim to empty the active visitors list
108                    # if the host doesn't have candy, remove all current visitors111                    # if the host doesn't have candy, remove all current visitors
109                    # and add them to the list of past visitors112                    # and add them to the list of past visitors
110                    if not host.candies:113                    if not host.candies:
111                        host.visited_from += host.current_visitors114                        host.visited_from += host.current_visitors
112                        host.current_visitors = []115                        host.current_visitors = []
113                        break116                        break
114117
115                    # determine the next kid by comparing initiatives118                    # determine the next kid by comparing initiatives
116                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)119                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)
117                    # find candy for the next kid120                    # find candy for the next kid
n118                    next_candy = host.remove_candy(find_candy_with_biggest_mass)n121                    next_candy = host.remove_candy(FluxCapacitor.find_candy_with_biggest_mass)
119                    # add candy to kid's basket122                    # add candy to kid's basket
120                    next_kid.add_candy(next_candy)123                    next_kid.add_candy(next_candy)
121                    # save the kid in the list of past visitors and remove it from active visitors124                    # save the kid in the list of past visitors and remove it from active visitors
122                    host.visited_from.append(next_kid)125                    host.visited_from.append(next_kid)
123                    host.current_visitors.remove(next_kid)126                    host.current_visitors.remove(next_kid)
124127
125            # the last step is to add all children that have received critical mass to a set128            # the last step is to add all children that have received critical mass to a set
126            irridated_kids = set()129            irridated_kids = set()
t127            for kid in kids:t130            for kid in self.kids:
128                if kid.is_critical():131                if kid.is_critical():
129                    irridated_kids.add(kid)132                    irridated_kids.add(kid)
130            if irridated_kids:133            if irridated_kids:
131                return irridated_kids134                return irridated_kids
132135
133        return None136        return None
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1import mathf1import math
22
33
4class Candy:4class Candy:
5    def __init__(self, mass, uranium):5    def __init__(self, mass, uranium):
6        self.mass = mass6        self.mass = mass
7        self.uranium = uranium7        self.uranium = uranium
88
9    def get_uranium_quantity(self):9    def get_uranium_quantity(self):
10        """Return the quantity of uranium in grams."""10        """Return the quantity of uranium in grams."""
11        return self.mass * self.uranium11        return self.mass * self.uranium
1212
13    def get_mass(self):13    def get_mass(self):
14        return self.mass14        return self.mass
1515
1616
17class Person:17class Person:
18    def __init__(self, position):18    def __init__(self, position):
19        self.position = position19        self.position = position
2020
21    def get_position(self):21    def get_position(self):
22        return self.position22        return self.position
2323
24    def set_position(self, position):24    def set_position(self, position):
25        self.position = position25        self.position = position
2626
27    @staticmethod27    @staticmethod
28    def get_distance(person_1, person_2):28    def get_distance(person_1, person_2):
29        """This function calculates the distance between two people."""29        """This function calculates the distance between two people."""
30        dx = person_1.position[0] - person_2.position[0]30        dx = person_1.position[0] - person_2.position[0]
31        dy = person_1.position[1] - person_2.position[1]31        dy = person_1.position[1] - person_2.position[1]
32        return math.sqrt(dx ** 2 + dy ** 2)32        return math.sqrt(dx ** 2 + dy ** 2)
3333
3434
35class Kid(Person):35class Kid(Person):
36    def __init__(self, position, initiative):36    def __init__(self, position, initiative):
37        super().__init__(position)37        super().__init__(position)
38        self.initiative = initiative38        self.initiative = initiative
39        self.basket = list()39        self.basket = list()
4040
41    def get_initiative(self):41    def get_initiative(self):
42        return self.initiative42        return self.initiative
4343
44    def add_candy(self, candy_to_add):44    def add_candy(self, candy_to_add):
45        self.basket.append(candy_to_add)45        self.basket.append(candy_to_add)
4646
47    def is_critical(self):47    def is_critical(self):
48        """This function sums the uranium contents of all candies and returns true if sum > 20."""48        """This function sums the uranium contents of all candies and returns true if sum > 20."""
49        uranium_sum = 0.049        uranium_sum = 0.0
50        for candy in self.basket:50        for candy in self.basket:
51            uranium_sum += candy.get_uranium_quantity()51            uranium_sum += candy.get_uranium_quantity()
52        return uranium_sum > 2052        return uranium_sum > 20
5353
5454
55class Host(Person):55class Host(Person):
56    def __init__(self, position, candies):56    def __init__(self, position, candies):
57        super().__init__(position)57        super().__init__(position)
58        self.candies = [Candy(x, y) for x, y in candies]58        self.candies = [Candy(x, y) for x, y in candies]
59        self.visited_from = []  # add children that already visited a given host here59        self.visited_from = []  # add children that already visited a given host here
60        self.current_visitors = []  # add children that are visiting the host at the moment60        self.current_visitors = []  # add children that are visiting the host at the moment
6161
62    def remove_candy(self, func_remove_candy):62    def remove_candy(self, func_remove_candy):
63        # if the host doesn't have candy, do nothing63        # if the host doesn't have candy, do nothing
64        if not self.candies:64        if not self.candies:
65            return None65            return None
66        # save the candy to delete from the list66        # save the candy to delete from the list
67        candy_to_remove = func_remove_candy(self.candies)67        candy_to_remove = func_remove_candy(self.candies)
68        self.candies.remove(candy_to_remove)68        self.candies.remove(candy_to_remove)
69        return candy_to_remove69        return candy_to_remove
7070
7171
72def find_candy_with_biggest_mass(candies):72def find_candy_with_biggest_mass(candies):
73    return max(candies, key=lambda some_candy: some_candy.mass)73    return max(candies, key=lambda some_candy: some_candy.mass)
7474
7575
76class FluxCapacitor:76class FluxCapacitor:
77    def __init__(self, participants):77    def __init__(self, participants):
78        self.participants = participants78        self.participants = participants
7979
80    def get_victim(self):80    def get_victim(self):
81        kids = [person for person in self.participants if type(person) == Kid]81        kids = [person for person in self.participants if type(person) == Kid]
82        hosts = [person for person in self.participants if type(person) == Host]82        hosts = [person for person in self.participants if type(person) == Host]
8383
n84        children_visited_all_hosts = Falsen
85        while True:84        while True:
nn85            all_kids_visited_all_hosts = all(len(host.visited_from) == len(kids) for host in hosts)
86            if all_kids_visited_all_hosts:
87                break
88 
86            # first, determine for each kid which house it's going to visit89            # first, determine for each kid which house it's going to visit
87            for kid in kids:90            for kid in kids:
88                try:91                try:
89                    closest_unvisited_house = min([host for host in hosts if kid not in host.visited_from],92                    closest_unvisited_house = min([host for host in hosts if kid not in host.visited_from],
90                                                  key=lambda host: (93                                                  key=lambda host: (
91                                                      Person.get_distance(kid, host), host.position[0],94                                                      Person.get_distance(kid, host), host.position[0],
92                                                      host.position[1]))95                                                      host.position[1]))
93                # ValueError will be thrown if the iterable is empty (there are no unvisited hosts for the current kid)96                # ValueError will be thrown if the iterable is empty (there are no unvisited hosts for the current kid)
94                except ValueError:97                except ValueError:
n95                    children_visited_all_hosts = Truen
96                    break98                    break
9799
98                # mark the closest_unvisited_house as being actively visited by the respective kid100                # mark the closest_unvisited_house as being actively visited by the respective kid
99                closest_unvisited_house.current_visitors.append(kid)101                closest_unvisited_house.current_visitors.append(kid)
100                # the kid moves to the closest house, so change its coordinates102                # the kid moves to the closest house, so change its coordinates
101                kid.set_position(closest_unvisited_house.position)103                kid.set_position(closest_unvisited_house.position)
t102 t
103            # this line of code will break from the main loop if all hosts were visited
104            if children_visited_all_hosts:
105                break
106104
107            # secondly, make the hosts distribute the candy105            # secondly, make the hosts distribute the candy
108            for host in hosts:106            for host in hosts:
109                while host.current_visitors:  # aim to empty the active visitors list107                while host.current_visitors:  # aim to empty the active visitors list
110                    # if the host doesn't have candy, remove all current visitors108                    # if the host doesn't have candy, remove all current visitors
111                    # and add them to the list of past visitors109                    # and add them to the list of past visitors
112                    if not host.candies:110                    if not host.candies:
113                        host.visited_from += host.current_visitors111                        host.visited_from += host.current_visitors
114                        host.current_visitors = []112                        host.current_visitors = []
115                        break113                        break
116114
117                    # determine the next kid by comparing initiatives115                    # determine the next kid by comparing initiatives
118                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)116                    next_kid = max(host.current_visitors, key=lambda some_kid: some_kid.initiative)
119                    # find candy for the next kid117                    # find candy for the next kid
120                    next_candy = host.remove_candy(find_candy_with_biggest_mass)118                    next_candy = host.remove_candy(find_candy_with_biggest_mass)
121                    # add candy to kid's basket119                    # add candy to kid's basket
122                    next_kid.add_candy(next_candy)120                    next_kid.add_candy(next_candy)
123                    # save the kid in the list of past visitors and remove it from active visitors121                    # save the kid in the list of past visitors and remove it from active visitors
124                    host.visited_from.append(next_kid)122                    host.visited_from.append(next_kid)
125                    host.current_visitors.remove(next_kid)123                    host.current_visitors.remove(next_kid)
126124
127            # the last step is to add all children that have received critical mass to a set125            # the last step is to add all children that have received critical mass to a set
128            irridated_kids = set()126            irridated_kids = set()
129            for kid in kids:127            for kid in kids:
130                if kid.is_critical():128                if kid.is_critical():
131                    irridated_kids.add(kid)129                    irridated_kids.add(kid)
132            if irridated_kids:130            if irridated_kids:
133                return irridated_kids131                return irridated_kids
134132
135        return None133        return None
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op