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

Резултати
8 точки от тестове
1 точки от учител

9 точки общо

10 успешни теста
2 неуспешни теста
Код

  1def max_candy_by_mass(candies: list):
  2    """Return the Candy with the most Mass."""
  3    return max(candies, key=lambda candy: candy.get_mass())
  4
  5
  6def get_host_with_min_distance(kid, hosts):
  7    """Return the Host with the least Distance to the Kid."""
  8    return min(hosts,
  9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))
 10
 11
 12class Candy:
 13    """A Class that represents a Candy."""
 14
 15    def __init__(self, mass: float, uranium: float):
 16        self._mass = mass
 17        self._uranium = uranium
 18
 19    def get_mass(self):
 20        """Return the Mass of the Candy."""
 21        return self._mass
 22
 23    def get_uranium_quantity(self):
 24        """Return the total Amount of Uranium in the Candy."""
 25        return self._mass * self._uranium
 26
 27
 28class Person:
 29    """A Class that Represents a Person."""
 30
 31    def __init__(self, position: tuple):
 32        self._position = None
 33        self.set_position(position)
 34        self._basket = []
 35
 36    def get_position(self):
 37        """Return the Position of the Person."""
 38        return self._position
 39
 40    def set_position(self, position: tuple):
 41        """Change the Position of the Person."""
 42        self._position = position
 43
 44    def get_distance_to_person(self, person):
 45        """Return the Distance from the current Person to the passed in Person."""
 46        return ((self._position[0] - person.get_position()[0]) ** 2 + (
 47                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
 48
 49    def is_basket_empty(self):
 50        """Return true if the Basket is empty."""
 51        return not self._basket
 52
 53    def __repr__(self):
 54        return f'{self._position}, Basket: {len(self._basket)}'
 55
 56
 57class Kid(Person):
 58    """A Class that represents a Kid."""
 59
 60    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
 61
 62    def __init__(self, position: tuple, initiative: int):
 63        super().__init__(position)
 64        self._initiative = initiative
 65
 66    def get_initiative(self):
 67        """Return the Initiative of the Kid."""
 68        return self._initiative
 69
 70    def add_candy(self, candy: Candy or None):
 71        """Add a Candy to the Basket."""
 72        if not candy:
 73            return
 74
 75        self._basket.append(candy)
 76
 77    def is_critical(self):
 78        """Return true if the Uranium Amount in the Basket is more than 20g."""
 79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
 80
 81    def get_total_uranium_in_basket(self):
 82        """Get the total Amount of Uranium in the Basket."""
 83        return sum([candy.get_uranium_quantity() for candy in self._basket])
 84
 85    def __repr__(self):
 86        return (f'{super().__repr__()}, Initiative: {self._initiative},'
 87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')
 88
 89
 90class Host(Person):
 91    """A Class that represents a Host."""
 92
 93    def __init__(self, position: tuple, candies: list):
 94        super().__init__(position)
 95        self._basket = candies[:]
 96
 97    def remove_candy(self, candy_choosing_function):
 98        """Select a Candy from the Basket based on the passed in Function."""
 99        if not self._basket:
100            return None
101
102        chosen_candy = candy_choosing_function(self._basket)
103        self._basket.remove(chosen_candy)
104        return chosen_candy or None
105
106
107class FluxCapacitor:
108    """Class that represents a simulation of a Halloween night."""
109
110    def __init__(self, participants: set):
111        self._kids = []
112        self._hosts = []
113        self._hosts_visitation_table = {}
114        self._fill_participants(participants)
115
116    def _fill_participants(self, participants: set):
117        for participant in participants:
118            if type(participant) is Kid:
119                self._kids.append(participant)
120            else:
121                self._hosts.append(participant)
122
123    def get_victim(self):
124        """Simulate a Halloween night and return the first Kids that are critical."""
125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
126            if critical_kids is None:
127                return None
128
129        return set(critical_kids) or None
130
131    def _have_the_kids_visited_all_hosts(self):
132        """Return true if all the Kids have visited all the Hosts."""
133        return all([len(self._hosts_visitation_table.get(kid, set())) == len(self._hosts) for kid in self._kids])
134
135    def _simulate_one_iteration_of_trick_or_treat(self):
136        """Simulate one cycle of Kids taking Candy from Hosts.
137
138        Return the Kids that are critical after the Cycle or
139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
140        an empty List if there are no critical Kids after the Cycle or
141        all the Kids have visited all the Hosts.
142        """
143
144        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
145        none_critical_kids_sorted_by_initiative = sorted(
146            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
147            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
148        )
149
150        if (not none_critical_kids_sorted_by_initiative or
151                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):
152            return None
153
154        critical_kids = []
155        for kid in none_critical_kids_sorted_by_initiative:
156            hosts_not_visited_by_current_kid = list(
157                filter(
158                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),
159                    hosts_with_candies
160                )
161            )
162
163            if not hosts_not_visited_by_current_kid:
164                continue
165
166            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)
167            kid.set_position(min_dist_host.get_position())
168
169            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, set())
170            self._hosts_visitation_table[kid].add(min_dist_host)
171
172            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
173            kid.add_candy(removed_candy)
174
175            if kid.is_critical():
176                critical_kids.append(kid)
177
178        return critical_kids

.....EE.....
======================================================================
ERROR: test_real_case (test.FluxCapacitorTest)
Test with real case.
----------------------------------------------------------------------
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 115, in test_real_case
self.assertEqual(FluxCapacitor({kid1, kid2, host1, host2}).get_victim(), {kid1, kid2})
File "/tmp/solution.py", line 125, in get_victim
while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
File "/tmp/solution.py", line 172, in _simulate_one_iteration_of_trick_or_treat
removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
File "/tmp/solution.py", line 102, in remove_candy
chosen_candy = candy_choosing_function(self._basket)
File "/tmp/solution.py", line 3, in max_candy_by_mass
return max(candies, key=lambda candy: candy.get_mass())
File "/tmp/solution.py", line 3, in <lambda>
return max(candies, key=lambda candy: candy.get_mass())
AttributeError: 'tuple' object has no attribute 'get_mass'

======================================================================
ERROR: test_basic_usage (test.HostTest)
Test basic usage of Host class.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 65, in test_basic_usage
candy = host.remove_candy(compare_fun)
File "/tmp/solution.py", line 102, in remove_candy
chosen_candy = candy_choosing_function(self._basket)
File "/tmp/test.py", line 63, in <lambda>
compare_fun = lambda candies: min(candies, key=lambda candy: candy.get_mass())
File "/tmp/test.py", line 63, in <lambda>
compare_fun = lambda candies: min(candies, key=lambda candy: candy.get_mass())
AttributeError: 'tuple' object has no attribute 'get_mass'

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

FAILED (errors=2)

Дискусия
Филип Филчев
07.11.2023 14:39

Благодаря!
Георги Кунчев
07.11.2023 09:27

Като човек, който винаги качва пръв, както и за старанието да качиш толкова много версии, получаваш едина бонус точка за това домашно.
Филип Филчев
02.11.2023 23:00

Тези докстрингове в последната функция ми помагат на мен да проследя какво съм написал. Ще ги махна при финалното предаване.
Георги Кунчев
02.11.2023 18:20

Логически грешки не се показват при ъплоуд. Само учителите ги виждат, докато не се направят всички решения публични
Филип Филчев
02.11.2023 17:25

Питам дали има тестове, които тестват самото решение, не за компилация. Защото бях качил решението с грешки в логиката и се учудих, че се качи.
Георги Кунчев
02.11.2023 09:38

Да, за всяко домашно и предизвикателство се пускат тестове при качване, които имат за цел да верифицират сигнатурата на кода ти. С други думи - дали си използвал правилните имена на класове/функции и дали те връщат правилния тип данни. Ако всичко с теста е наред, направо се качва и се визуализира. Ако има проблем, ще видиш лога от тестовете, за да се ориентираш какво трябва да се оправи. Сега тествах и всичко изглежда наред, но ако имаш съмнение, че нещо не е сработило, кажи да погледна.
Филип Филчев
01.11.2023 21:40

Някакви тестове рънват ли се при качване?
История

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts,8    return min(hosts,
9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))
1010
1111
12class Candy:12class Candy:
13    """A Class that represents a Candy."""13    """A Class that represents a Candy."""
1414
15    def __init__(self, mass: float, uranium: float):15    def __init__(self, mass: float, uranium: float):
16        self._mass = mass16        self._mass = mass
17        self._uranium = uranium17        self._uranium = uranium
1818
19    def get_mass(self):19    def get_mass(self):
20        """Return the Mass of the Candy."""20        """Return the Mass of the Candy."""
21        return self._mass21        return self._mass
2222
23    def get_uranium_quantity(self):23    def get_uranium_quantity(self):
24        """Return the total Amount of Uranium in the Candy."""24        """Return the total Amount of Uranium in the Candy."""
25        return self._mass * self._uranium25        return self._mass * self._uranium
2626
2727
28class Person:28class Person:
29    """A Class that Represents a Person."""29    """A Class that Represents a Person."""
3030
31    def __init__(self, position: tuple):31    def __init__(self, position: tuple):
32        self._position = None32        self._position = None
33        self.set_position(position)33        self.set_position(position)
34        self._basket = []34        self._basket = []
3535
36    def get_position(self):36    def get_position(self):
37        """Return the Position of the Person."""37        """Return the Position of the Person."""
38        return self._position38        return self._position
3939
40    def set_position(self, position: tuple):40    def set_position(self, position: tuple):
41        """Change the Position of the Person."""41        """Change the Position of the Person."""
42        self._position = position42        self._position = position
4343
44    def get_distance_to_person(self, person):44    def get_distance_to_person(self, person):
45        """Return the Distance from the current Person to the passed in Person."""45        """Return the Distance from the current Person to the passed in Person."""
46        return ((self._position[0] - person.get_position()[0]) ** 2 + (46        return ((self._position[0] - person.get_position()[0]) ** 2 + (
47                self._position[1] - person.get_position()[1]) ** 2) ** 0.547                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4848
49    def is_basket_empty(self):49    def is_basket_empty(self):
50        """Return true if the Basket is empty."""50        """Return true if the Basket is empty."""
51        return not self._basket51        return not self._basket
5252
53    def __repr__(self):53    def __repr__(self):
54        return f'{self._position}, Basket: {len(self._basket)}'54        return f'{self._position}, Basket: {len(self._basket)}'
5555
5656
57class Kid(Person):57class Kid(Person):
58    """A Class that represents a Kid."""58    """A Class that represents a Kid."""
5959
60    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2060    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6161
62    def __init__(self, position: tuple, initiative: int):62    def __init__(self, position: tuple, initiative: int):
63        super().__init__(position)63        super().__init__(position)
64        self._initiative = initiative64        self._initiative = initiative
6565
66    def get_initiative(self):66    def get_initiative(self):
67        """Return the Initiative of the Kid."""67        """Return the Initiative of the Kid."""
68        return self._initiative68        return self._initiative
6969
70    def add_candy(self, candy: Candy or None):70    def add_candy(self, candy: Candy or None):
71        """Add a Candy to the Basket."""71        """Add a Candy to the Basket."""
72        if not candy:72        if not candy:
73            return73            return
7474
75        self._basket.append(candy)75        self._basket.append(candy)
7676
77    def is_critical(self):77    def is_critical(self):
78        """Return true if the Uranium Amount in the Basket is more than 20g."""78        """Return true if the Uranium Amount in the Basket is more than 20g."""
79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
8080
81    def get_total_uranium_in_basket(self):81    def get_total_uranium_in_basket(self):
82        """Get the total Amount of Uranium in the Basket."""82        """Get the total Amount of Uranium in the Basket."""
83        return sum([candy.get_uranium_quantity() for candy in self._basket])83        return sum([candy.get_uranium_quantity() for candy in self._basket])
8484
85    def __repr__(self):85    def __repr__(self):
86        return (f'{super().__repr__()}, Initiative: {self._initiative},'86        return (f'{super().__repr__()}, Initiative: {self._initiative},'
87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')
8888
8989
90class Host(Person):90class Host(Person):
91    """A Class that represents a Host."""91    """A Class that represents a Host."""
9292
93    def __init__(self, position: tuple, candies: list):93    def __init__(self, position: tuple, candies: list):
94        super().__init__(position)94        super().__init__(position)
95        self._basket = candies[:]95        self._basket = candies[:]
9696
97    def remove_candy(self, candy_choosing_function):97    def remove_candy(self, candy_choosing_function):
98        """Select a Candy from the Basket based on the passed in Function."""98        """Select a Candy from the Basket based on the passed in Function."""
99        if not self._basket:99        if not self._basket:
100            return None100            return None
101101
102        chosen_candy = candy_choosing_function(self._basket)102        chosen_candy = candy_choosing_function(self._basket)
103        self._basket.remove(chosen_candy)103        self._basket.remove(chosen_candy)
104        return chosen_candy or None104        return chosen_candy or None
105105
106106
107class FluxCapacitor:107class FluxCapacitor:
108    """Class that represents a simulation of a Halloween night."""108    """Class that represents a simulation of a Halloween night."""
109109
110    def __init__(self, participants: set):110    def __init__(self, participants: set):
111        self._kids = []111        self._kids = []
112        self._hosts = []112        self._hosts = []
113        self._hosts_visitation_table = {}113        self._hosts_visitation_table = {}
114        self._fill_participants(participants)114        self._fill_participants(participants)
115115
116    def _fill_participants(self, participants: set):116    def _fill_participants(self, participants: set):
117        for participant in participants:117        for participant in participants:
118            if type(participant) is Kid:118            if type(participant) is Kid:
119                self._kids.append(participant)119                self._kids.append(participant)
120            else:120            else:
121                self._hosts.append(participant)121                self._hosts.append(participant)
122122
123    def get_victim(self):123    def get_victim(self):
124        """Simulate a Halloween night and return the first Kids that are critical."""124        """Simulate a Halloween night and return the first Kids that are critical."""
125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
126            if critical_kids is None:126            if critical_kids is None:
127                return None127                return None
128128
129        return set(critical_kids) or None129        return set(critical_kids) or None
130130
131    def _have_the_kids_visited_all_hosts(self):131    def _have_the_kids_visited_all_hosts(self):
132        """Return true if all the Kids have visited all the Hosts."""132        """Return true if all the Kids have visited all the Hosts."""
n133        return all([self._hosts in self._hosts_visitation_table.get(kid, []) for kid in self._kids])n133        return all([len(self._hosts_visitation_table.get(kid, set())) == len(self._hosts) for kid in self._kids])
134134
135    def _simulate_one_iteration_of_trick_or_treat(self):135    def _simulate_one_iteration_of_trick_or_treat(self):
136        """Simulate one cycle of Kids taking Candy from Hosts.136        """Simulate one cycle of Kids taking Candy from Hosts.
137137
138        Return the Kids that are critical after the Cycle or138        Return the Kids that are critical after the Cycle or
139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
140        an empty List if there are no critical Kids after the Cycle or140        an empty List if there are no critical Kids after the Cycle or
141        all the Kids have visited all the Hosts.141        all the Kids have visited all the Hosts.
142        """142        """
143143
144        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))144        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
145        none_critical_kids_sorted_by_initiative = sorted(145        none_critical_kids_sorted_by_initiative = sorted(
146            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),146            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
147            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True147            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
148        )148        )
149149
150        if (not none_critical_kids_sorted_by_initiative or150        if (not none_critical_kids_sorted_by_initiative or
151                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):151                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):
152            return None152            return None
153153
154        critical_kids = []154        critical_kids = []
155        for kid in none_critical_kids_sorted_by_initiative:155        for kid in none_critical_kids_sorted_by_initiative:
156            hosts_not_visited_by_current_kid = list(156            hosts_not_visited_by_current_kid = list(
157                filter(157                filter(
158                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),158                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),
159                    hosts_with_candies159                    hosts_with_candies
160                )160                )
161            )161            )
162162
163            if not hosts_not_visited_by_current_kid:163            if not hosts_not_visited_by_current_kid:
164                continue164                continue
165165
166            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)166            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)
167            kid.set_position(min_dist_host.get_position())167            kid.set_position(min_dist_host.get_position())
168168
t169            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, [])t169            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, set())
170            self._hosts_visitation_table[kid].append(min_dist_host)170            self._hosts_visitation_table[kid].add(min_dist_host)
171171
172            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)172            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
173            kid.add_candy(removed_candy)173            kid.add_candy(removed_candy)
174174
175            if kid.is_critical():175            if kid.is_critical():
176                critical_kids.append(kid)176                critical_kids.append(kid)
177177
178        return critical_kids178        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts,8    return min(hosts,
9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))
1010
1111
12class Candy:12class Candy:
13    """A Class that represents a Candy."""13    """A Class that represents a Candy."""
1414
15    def __init__(self, mass: float, uranium: float):15    def __init__(self, mass: float, uranium: float):
16        self._mass = mass16        self._mass = mass
17        self._uranium = uranium17        self._uranium = uranium
1818
19    def get_mass(self):19    def get_mass(self):
20        """Return the Mass of the Candy."""20        """Return the Mass of the Candy."""
21        return self._mass21        return self._mass
2222
23    def get_uranium_quantity(self):23    def get_uranium_quantity(self):
24        """Return the total Amount of Uranium in the Candy."""24        """Return the total Amount of Uranium in the Candy."""
25        return self._mass * self._uranium25        return self._mass * self._uranium
2626
2727
28class Person:28class Person:
29    """A Class that Represents a Person."""29    """A Class that Represents a Person."""
3030
31    def __init__(self, position: tuple):31    def __init__(self, position: tuple):
32        self._position = None32        self._position = None
33        self.set_position(position)33        self.set_position(position)
34        self._basket = []34        self._basket = []
3535
36    def get_position(self):36    def get_position(self):
37        """Return the Position of the Person."""37        """Return the Position of the Person."""
38        return self._position38        return self._position
3939
40    def set_position(self, position: tuple):40    def set_position(self, position: tuple):
41        """Change the Position of the Person."""41        """Change the Position of the Person."""
42        self._position = position42        self._position = position
4343
44    def get_distance_to_person(self, person):44    def get_distance_to_person(self, person):
45        """Return the Distance from the current Person to the passed in Person."""45        """Return the Distance from the current Person to the passed in Person."""
46        return ((self._position[0] - person.get_position()[0]) ** 2 + (46        return ((self._position[0] - person.get_position()[0]) ** 2 + (
47                self._position[1] - person.get_position()[1]) ** 2) ** 0.547                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4848
49    def is_basket_empty(self):49    def is_basket_empty(self):
50        """Return true if the Basket is empty."""50        """Return true if the Basket is empty."""
51        return not self._basket51        return not self._basket
5252
53    def __repr__(self):53    def __repr__(self):
54        return f'{self._position}, Basket: {len(self._basket)}'54        return f'{self._position}, Basket: {len(self._basket)}'
5555
5656
57class Kid(Person):57class Kid(Person):
58    """A Class that represents a Kid."""58    """A Class that represents a Kid."""
5959
60    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2060    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6161
62    def __init__(self, position: tuple, initiative: int):62    def __init__(self, position: tuple, initiative: int):
63        super().__init__(position)63        super().__init__(position)
64        self._initiative = initiative64        self._initiative = initiative
6565
66    def get_initiative(self):66    def get_initiative(self):
67        """Return the Initiative of the Kid."""67        """Return the Initiative of the Kid."""
68        return self._initiative68        return self._initiative
6969
70    def add_candy(self, candy: Candy or None):70    def add_candy(self, candy: Candy or None):
71        """Add a Candy to the Basket."""71        """Add a Candy to the Basket."""
72        if not candy:72        if not candy:
73            return73            return
7474
75        self._basket.append(candy)75        self._basket.append(candy)
7676
77    def is_critical(self):77    def is_critical(self):
78        """Return true if the Uranium Amount in the Basket is more than 20g."""78        """Return true if the Uranium Amount in the Basket is more than 20g."""
79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
8080
81    def get_total_uranium_in_basket(self):81    def get_total_uranium_in_basket(self):
82        """Get the total Amount of Uranium in the Basket."""82        """Get the total Amount of Uranium in the Basket."""
83        return sum([candy.get_uranium_quantity() for candy in self._basket])83        return sum([candy.get_uranium_quantity() for candy in self._basket])
8484
85    def __repr__(self):85    def __repr__(self):
86        return (f'{super().__repr__()}, Initiative: {self._initiative},'86        return (f'{super().__repr__()}, Initiative: {self._initiative},'
87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')
8888
8989
90class Host(Person):90class Host(Person):
91    """A Class that represents a Host."""91    """A Class that represents a Host."""
9292
93    def __init__(self, position: tuple, candies: list):93    def __init__(self, position: tuple, candies: list):
94        super().__init__(position)94        super().__init__(position)
95        self._basket = candies[:]95        self._basket = candies[:]
9696
97    def remove_candy(self, candy_choosing_function):97    def remove_candy(self, candy_choosing_function):
98        """Select a Candy from the Basket based on the passed in Function."""98        """Select a Candy from the Basket based on the passed in Function."""
99        if not self._basket:99        if not self._basket:
100            return None100            return None
101101
102        chosen_candy = candy_choosing_function(self._basket)102        chosen_candy = candy_choosing_function(self._basket)
103        self._basket.remove(chosen_candy)103        self._basket.remove(chosen_candy)
104        return chosen_candy or None104        return chosen_candy or None
105105
106106
107class FluxCapacitor:107class FluxCapacitor:
108    """Class that represents a simulation of a Halloween night."""108    """Class that represents a simulation of a Halloween night."""
109109
110    def __init__(self, participants: set):110    def __init__(self, participants: set):
111        self._kids = []111        self._kids = []
112        self._hosts = []112        self._hosts = []
113        self._hosts_visitation_table = {}113        self._hosts_visitation_table = {}
114        self._fill_participants(participants)114        self._fill_participants(participants)
115115
116    def _fill_participants(self, participants: set):116    def _fill_participants(self, participants: set):
117        for participant in participants:117        for participant in participants:
118            if type(participant) is Kid:118            if type(participant) is Kid:
119                self._kids.append(participant)119                self._kids.append(participant)
120            else:120            else:
121                self._hosts.append(participant)121                self._hosts.append(participant)
122122
123    def get_victim(self):123    def get_victim(self):
124        """Simulate a Halloween night and return the first Kids that are critical."""124        """Simulate a Halloween night and return the first Kids that are critical."""
125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
126            if critical_kids is None:126            if critical_kids is None:
127                return None127                return None
128128
129        return set(critical_kids) or None129        return set(critical_kids) or None
130130
131    def _have_the_kids_visited_all_hosts(self):131    def _have_the_kids_visited_all_hosts(self):
132        """Return true if all the Kids have visited all the Hosts."""132        """Return true if all the Kids have visited all the Hosts."""
n133        return all([len(self._hosts_visitation_table.get(kid, set())) == len(self._hosts) for kid in self._kids])n133        return all([self._hosts in self._hosts_visitation_table.get(kid, []) for kid in self._kids])
134134
135    def _simulate_one_iteration_of_trick_or_treat(self):135    def _simulate_one_iteration_of_trick_or_treat(self):
136        """Simulate one cycle of Kids taking Candy from Hosts.136        """Simulate one cycle of Kids taking Candy from Hosts.
137137
138        Return the Kids that are critical after the Cycle or138        Return the Kids that are critical after the Cycle or
139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
140        an empty List if there are no critical Kids after the Cycle or140        an empty List if there are no critical Kids after the Cycle or
141        all the Kids have visited all the Hosts.141        all the Kids have visited all the Hosts.
142        """142        """
143143
144        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))144        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
145        none_critical_kids_sorted_by_initiative = sorted(145        none_critical_kids_sorted_by_initiative = sorted(
146            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),146            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
147            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True147            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
148        )148        )
149149
150        if (not none_critical_kids_sorted_by_initiative or150        if (not none_critical_kids_sorted_by_initiative or
151                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):151                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):
152            return None152            return None
153153
154        critical_kids = []154        critical_kids = []
155        for kid in none_critical_kids_sorted_by_initiative:155        for kid in none_critical_kids_sorted_by_initiative:
156            hosts_not_visited_by_current_kid = list(156            hosts_not_visited_by_current_kid = list(
157                filter(157                filter(
158                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),158                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),
159                    hosts_with_candies159                    hosts_with_candies
160                )160                )
161            )161            )
162162
163            if not hosts_not_visited_by_current_kid:163            if not hosts_not_visited_by_current_kid:
164                continue164                continue
165165
166            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)166            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)
167            kid.set_position(min_dist_host.get_position())167            kid.set_position(min_dist_host.get_position())
168168
t169            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, set())t169            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, [])
170            self._hosts_visitation_table[kid].add(min_dist_host)170            self._hosts_visitation_table[kid].append(min_dist_host)
171171
172            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)172            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
173            kid.add_candy(removed_candy)173            kid.add_candy(removed_candy)
174174
175            if kid.is_critical():175            if kid.is_critical():
176                critical_kids.append(kid)176                critical_kids.append(kid)
177177
178        return critical_kids178        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts,8    return min(hosts,
9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))
1010
1111
12class Candy:12class Candy:
13    """A Class that represents a Candy."""13    """A Class that represents a Candy."""
1414
15    def __init__(self, mass: float, uranium: float):15    def __init__(self, mass: float, uranium: float):
16        self._mass = mass16        self._mass = mass
17        self._uranium = uranium17        self._uranium = uranium
1818
19    def get_mass(self):19    def get_mass(self):
20        """Return the Mass of the Candy."""20        """Return the Mass of the Candy."""
21        return self._mass21        return self._mass
2222
23    def get_uranium_quantity(self):23    def get_uranium_quantity(self):
24        """Return the total Amount of Uranium in the Candy."""24        """Return the total Amount of Uranium in the Candy."""
25        return self._mass * self._uranium25        return self._mass * self._uranium
2626
2727
28class Person:28class Person:
29    """A Class that Represents a Person."""29    """A Class that Represents a Person."""
3030
31    def __init__(self, position: tuple):31    def __init__(self, position: tuple):
32        self._position = None32        self._position = None
33        self.set_position(position)33        self.set_position(position)
34        self._basket = []34        self._basket = []
3535
36    def get_position(self):36    def get_position(self):
37        """Return the Position of the Person."""37        """Return the Position of the Person."""
38        return self._position38        return self._position
3939
40    def set_position(self, position: tuple):40    def set_position(self, position: tuple):
41        """Change the Position of the Person."""41        """Change the Position of the Person."""
42        self._position = position42        self._position = position
4343
44    def get_distance_to_person(self, person):44    def get_distance_to_person(self, person):
45        """Return the Distance from the current Person to the passed in Person."""45        """Return the Distance from the current Person to the passed in Person."""
46        return ((self._position[0] - person.get_position()[0]) ** 2 + (46        return ((self._position[0] - person.get_position()[0]) ** 2 + (
47                self._position[1] - person.get_position()[1]) ** 2) ** 0.547                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4848
49    def is_basket_empty(self):49    def is_basket_empty(self):
50        """Return true if the Basket is empty."""50        """Return true if the Basket is empty."""
51        return not self._basket51        return not self._basket
5252
53    def __repr__(self):53    def __repr__(self):
54        return f'{self._position}, Basket: {len(self._basket)}'54        return f'{self._position}, Basket: {len(self._basket)}'
5555
5656
57class Kid(Person):57class Kid(Person):
58    """A Class that represents a Kid."""58    """A Class that represents a Kid."""
5959
60    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2060    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6161
62    def __init__(self, position: tuple, initiative: int):62    def __init__(self, position: tuple, initiative: int):
63        super().__init__(position)63        super().__init__(position)
64        self._initiative = initiative64        self._initiative = initiative
6565
66    def get_initiative(self):66    def get_initiative(self):
67        """Return the Initiative of the Kid."""67        """Return the Initiative of the Kid."""
68        return self._initiative68        return self._initiative
6969
70    def add_candy(self, candy: Candy or None):70    def add_candy(self, candy: Candy or None):
71        """Add a Candy to the Basket."""71        """Add a Candy to the Basket."""
72        if not candy:72        if not candy:
73            return73            return
7474
75        self._basket.append(candy)75        self._basket.append(candy)
7676
77    def is_critical(self):77    def is_critical(self):
78        """Return true if the Uranium Amount in the Basket is more than 20g."""78        """Return true if the Uranium Amount in the Basket is more than 20g."""
79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
8080
81    def get_total_uranium_in_basket(self):81    def get_total_uranium_in_basket(self):
82        """Get the total Amount of Uranium in the Basket."""82        """Get the total Amount of Uranium in the Basket."""
83        return sum([candy.get_uranium_quantity() for candy in self._basket])83        return sum([candy.get_uranium_quantity() for candy in self._basket])
8484
85    def __repr__(self):85    def __repr__(self):
86        return (f'{super().__repr__()}, Initiative: {self._initiative},'86        return (f'{super().__repr__()}, Initiative: {self._initiative},'
87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')
8888
8989
90class Host(Person):90class Host(Person):
91    """A Class that represents a Host."""91    """A Class that represents a Host."""
9292
93    def __init__(self, position: tuple, candies: list):93    def __init__(self, position: tuple, candies: list):
94        super().__init__(position)94        super().__init__(position)
95        self._basket = candies[:]95        self._basket = candies[:]
9696
97    def remove_candy(self, candy_choosing_function):97    def remove_candy(self, candy_choosing_function):
98        """Select a Candy from the Basket based on the passed in Function."""98        """Select a Candy from the Basket based on the passed in Function."""
99        if not self._basket:99        if not self._basket:
100            return None100            return None
101101
102        chosen_candy = candy_choosing_function(self._basket)102        chosen_candy = candy_choosing_function(self._basket)
103        self._basket.remove(chosen_candy)103        self._basket.remove(chosen_candy)
104        return chosen_candy or None104        return chosen_candy or None
105105
106106
107class FluxCapacitor:107class FluxCapacitor:
108    """Class that represents a simulation of a Halloween night."""108    """Class that represents a simulation of a Halloween night."""
109109
110    def __init__(self, participants: set):110    def __init__(self, participants: set):
111        self._kids = []111        self._kids = []
112        self._hosts = []112        self._hosts = []
113        self._hosts_visitation_table = {}113        self._hosts_visitation_table = {}
114        self._fill_participants(participants)114        self._fill_participants(participants)
115115
116    def _fill_participants(self, participants: set):116    def _fill_participants(self, participants: set):
117        for participant in participants:117        for participant in participants:
118            if type(participant) is Kid:118            if type(participant) is Kid:
119                self._kids.append(participant)119                self._kids.append(participant)
120            else:120            else:
121                self._hosts.append(participant)121                self._hosts.append(participant)
122122
123    def get_victim(self):123    def get_victim(self):
124        """Simulate a Halloween night and return the first Kids that are critical."""124        """Simulate a Halloween night and return the first Kids that are critical."""
125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
126            if critical_kids is None:126            if critical_kids is None:
127                return None127                return None
128128
129        return set(critical_kids) or None129        return set(critical_kids) or None
130130
131    def _have_the_kids_visited_all_hosts(self):131    def _have_the_kids_visited_all_hosts(self):
132        """Return true if all the Kids have visited all the Hosts."""132        """Return true if all the Kids have visited all the Hosts."""
133        return all([len(self._hosts_visitation_table.get(kid, set())) == len(self._hosts) for kid in self._kids])133        return all([len(self._hosts_visitation_table.get(kid, set())) == len(self._hosts) for kid in self._kids])
134134
135    def _simulate_one_iteration_of_trick_or_treat(self):135    def _simulate_one_iteration_of_trick_or_treat(self):
136        """Simulate one cycle of Kids taking Candy from Hosts.136        """Simulate one cycle of Kids taking Candy from Hosts.
137137
138        Return the Kids that are critical after the Cycle or138        Return the Kids that are critical after the Cycle or
139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
t140        an empty List if there are no critical Kids after the Cycle.t140        an empty List if there are no critical Kids after the Cycle or
141        all the Kids have visited all the Hosts.
141        """142        """
142143
143        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))144        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
144        none_critical_kids_sorted_by_initiative = sorted(145        none_critical_kids_sorted_by_initiative = sorted(
145            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),146            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
146            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True147            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
147        )148        )
148149
149        if (not none_critical_kids_sorted_by_initiative or150        if (not none_critical_kids_sorted_by_initiative or
150                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):151                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):
151            return None152            return None
152153
153        critical_kids = []154        critical_kids = []
154        for kid in none_critical_kids_sorted_by_initiative:155        for kid in none_critical_kids_sorted_by_initiative:
155            hosts_not_visited_by_current_kid = list(156            hosts_not_visited_by_current_kid = list(
156                filter(157                filter(
157                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),158                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),
158                    hosts_with_candies159                    hosts_with_candies
159                )160                )
160            )161            )
161162
162            if not hosts_not_visited_by_current_kid:163            if not hosts_not_visited_by_current_kid:
163                continue164                continue
164165
165            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)166            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)
166            kid.set_position(min_dist_host.get_position())167            kid.set_position(min_dist_host.get_position())
167168
168            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, set())169            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, set())
169            self._hosts_visitation_table[kid].add(min_dist_host)170            self._hosts_visitation_table[kid].add(min_dist_host)
170171
171            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)172            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
172            kid.add_candy(removed_candy)173            kid.add_candy(removed_candy)
173174
174            if kid.is_critical():175            if kid.is_critical():
175                critical_kids.append(kid)176                critical_kids.append(kid)
176177
177        return critical_kids178        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
n8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))n8    return min(hosts,
9               key=(lambda host: (host.get_distance_to_person(kid), host.get_position()[0], host.get_position()[1])))
910
1011
11class Candy:12class Candy:
12    """A Class that represents a Candy."""13    """A Class that represents a Candy."""
1314
14    def __init__(self, mass: float, uranium: float):15    def __init__(self, mass: float, uranium: float):
15        self._mass = mass16        self._mass = mass
16        self._uranium = uranium17        self._uranium = uranium
1718
18    def get_mass(self):19    def get_mass(self):
19        """Return the Mass of the Candy."""20        """Return the Mass of the Candy."""
20        return self._mass21        return self._mass
2122
22    def get_uranium_quantity(self):23    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""24        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium25        return self._mass * self._uranium
2526
2627
27class Person:28class Person:
28    """A Class that Represents a Person."""29    """A Class that Represents a Person."""
2930
30    def __init__(self, position: tuple):31    def __init__(self, position: tuple):
31        self._position = None32        self._position = None
32        self.set_position(position)33        self.set_position(position)
33        self._basket = []34        self._basket = []
3435
35    def get_position(self):36    def get_position(self):
36        """Return the Position of the Person."""37        """Return the Position of the Person."""
37        return self._position38        return self._position
3839
39    def set_position(self, position: tuple):40    def set_position(self, position: tuple):
40        """Change the Position of the Person."""41        """Change the Position of the Person."""
41        self._position = position42        self._position = position
4243
43    def get_distance_to_person(self, person):44    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""45        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (46        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.547                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4748
48    def is_basket_empty(self):49    def is_basket_empty(self):
49        """Return true if the Basket is empty."""50        """Return true if the Basket is empty."""
50        return not self._basket51        return not self._basket
5152
52    def __repr__(self):53    def __repr__(self):
53        return f'{self._position}, Basket: {len(self._basket)}'54        return f'{self._position}, Basket: {len(self._basket)}'
5455
5556
56class Kid(Person):57class Kid(Person):
57    """A Class that represents a Kid."""58    """A Class that represents a Kid."""
5859
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2060    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6061
61    def __init__(self, position: tuple, initiative: int):62    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)63        super().__init__(position)
63        self._initiative = initiative64        self._initiative = initiative
6465
65    def get_initiative(self):66    def get_initiative(self):
66        """Return the Initiative of the Kid."""67        """Return the Initiative of the Kid."""
67        return self._initiative68        return self._initiative
6869
69    def add_candy(self, candy: Candy or None):70    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""71        """Add a Candy to the Basket."""
71        if not candy:72        if not candy:
72            return73            return
7374
74        self._basket.append(candy)75        self._basket.append(candy)
7576
76    def is_critical(self):77    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""78        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS79        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7980
80    def get_total_uranium_in_basket(self):81    def get_total_uranium_in_basket(self):
81        """Get the total Amount of Uranium in the Basket."""82        """Get the total Amount of Uranium in the Basket."""
82        return sum([candy.get_uranium_quantity() for candy in self._basket])83        return sum([candy.get_uranium_quantity() for candy in self._basket])
8384
84    def __repr__(self):85    def __repr__(self):
85        return (f'{super().__repr__()}, Initiative: {self._initiative},'86        return (f'{super().__repr__()}, Initiative: {self._initiative},'
86                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')87                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')
8788
8889
89class Host(Person):90class Host(Person):
90    """A Class that represents a Host."""91    """A Class that represents a Host."""
9192
92    def __init__(self, position: tuple, candies: list):93    def __init__(self, position: tuple, candies: list):
93        super().__init__(position)94        super().__init__(position)
94        self._basket = candies[:]95        self._basket = candies[:]
9596
96    def remove_candy(self, candy_choosing_function):97    def remove_candy(self, candy_choosing_function):
97        """Select a Candy from the Basket based on the passed in Function."""98        """Select a Candy from the Basket based on the passed in Function."""
98        if not self._basket:99        if not self._basket:
99            return None100            return None
100101
101        chosen_candy = candy_choosing_function(self._basket)102        chosen_candy = candy_choosing_function(self._basket)
102        self._basket.remove(chosen_candy)103        self._basket.remove(chosen_candy)
103        return chosen_candy or None104        return chosen_candy or None
104105
105106
106class FluxCapacitor:107class FluxCapacitor:
107    """Class that represents a simulation of a Halloween night."""108    """Class that represents a simulation of a Halloween night."""
108109
109    def __init__(self, participants: set):110    def __init__(self, participants: set):
110        self._kids = []111        self._kids = []
111        self._hosts = []112        self._hosts = []
nn113        self._hosts_visitation_table = {}
112        self._fill_participants(participants)114        self._fill_participants(participants)
113115
114    def _fill_participants(self, participants: set):116    def _fill_participants(self, participants: set):
115        for participant in participants:117        for participant in participants:
116            if type(participant) is Kid:118            if type(participant) is Kid:
117                self._kids.append(participant)119                self._kids.append(participant)
118            else:120            else:
119                self._hosts.append(participant)121                self._hosts.append(participant)
120122
121    def get_victim(self):123    def get_victim(self):
122        """Simulate a Halloween night and return the first Kids that are critical."""124        """Simulate a Halloween night and return the first Kids that are critical."""
123        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):125        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
124            if critical_kids is None:126            if critical_kids is None:
125                return None127                return None
126128
127        return set(critical_kids) or None129        return set(critical_kids) or None
128130
nn131    def _have_the_kids_visited_all_hosts(self):
132        """Return true if all the Kids have visited all the Hosts."""
133        return all([len(self._hosts_visitation_table.get(kid, set())) == len(self._hosts) for kid in self._kids])
134 
129    def _simulate_one_iteration_of_trick_or_treat(self):135    def _simulate_one_iteration_of_trick_or_treat(self):
130        """Simulate one cycle of Kids taking Candy from Hosts.136        """Simulate one cycle of Kids taking Candy from Hosts.
131137
132        Return the Kids that are critical after the Cycle or138        Return the Kids that are critical after the Cycle or
133        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or139        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
134        an empty List if there are no critical Kids after the Cycle.140        an empty List if there are no critical Kids after the Cycle.
135        """141        """
136142
137        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))143        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
138        none_critical_kids_sorted_by_initiative = sorted(144        none_critical_kids_sorted_by_initiative = sorted(
139            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),145            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
140            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True146            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
141        )147        )
142148
n143        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:n149        if (not none_critical_kids_sorted_by_initiative or
150                not hosts_with_candies or self._have_the_kids_visited_all_hosts()):
144            return None151            return None
145152
146        critical_kids = []153        critical_kids = []
147        for kid in none_critical_kids_sorted_by_initiative:154        for kid in none_critical_kids_sorted_by_initiative:
nn155            hosts_not_visited_by_current_kid = list(
156                filter(
157                    lambda curr_host: curr_host not in self._hosts_visitation_table.get(kid, set()),
158                    hosts_with_candies
159                )
160            )
161 
162            if not hosts_not_visited_by_current_kid:
163                continue
164 
148            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)165            min_dist_host = get_host_with_min_distance(kid, hosts_not_visited_by_current_kid)
149            kid.set_position(min_dist_host.get_position())166            kid.set_position(min_dist_host.get_position())
tt167 
168            self._hosts_visitation_table[kid] = self._hosts_visitation_table.get(kid, set())
169            self._hosts_visitation_table[kid].add(min_dist_host)
150170
151            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)171            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
152            kid.add_candy(removed_candy)172            kid.add_candy(removed_candy)
153173
154            if kid.is_critical():174            if kid.is_critical():
155                critical_kids.append(kid)175                critical_kids.append(kid)
156176
157        return critical_kids177        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
n53        return f'{self._position}'n53        return f'{self._position}, Basket: {len(self._basket)}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
nn78        return self.get_total_uranium_in_basket() > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
79 
80    def get_total_uranium_in_basket(self):
81        """Get the total Amount of Uranium in the Basket."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS82        return sum([candy.get_uranium_quantity() for candy in self._basket])
7983
80    def __repr__(self):84    def __repr__(self):
t81        return f'{super().__repr__()} : {self._initiative}'t85        return (f'{super().__repr__()}, Initiative: {self._initiative},'
86                f' Total Uranium: {self.get_total_uranium_in_basket():.2f}g')
8287
8388
84class Host(Person):89class Host(Person):
85    """A Class that represents a Host."""90    """A Class that represents a Host."""
8691
87    def __init__(self, position: tuple, candies: list):92    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)93        super().__init__(position)
89        self._basket = candies[:]94        self._basket = candies[:]
9095
91    def remove_candy(self, candy_choosing_function):96    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""97        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:98        if not self._basket:
94            return None99            return None
95100
96        chosen_candy = candy_choosing_function(self._basket)101        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)102        self._basket.remove(chosen_candy)
98        return chosen_candy or None103        return chosen_candy or None
99104
100105
101class FluxCapacitor:106class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""107    """Class that represents a simulation of a Halloween night."""
103108
104    def __init__(self, participants: set):109    def __init__(self, participants: set):
105        self._kids = []110        self._kids = []
106        self._hosts = []111        self._hosts = []
107        self._fill_participants(participants)112        self._fill_participants(participants)
108113
109    def _fill_participants(self, participants: set):114    def _fill_participants(self, participants: set):
110        for participant in participants:115        for participant in participants:
111            if type(participant) is Kid:116            if type(participant) is Kid:
112                self._kids.append(participant)117                self._kids.append(participant)
113            else:118            else:
114                self._hosts.append(participant)119                self._hosts.append(participant)
115120
116    def get_victim(self):121    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""122        """Simulate a Halloween night and return the first Kids that are critical."""
118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):123        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
119            if critical_kids is None:124            if critical_kids is None:
120                return None125                return None
121126
122        return set(critical_kids) or None127        return set(critical_kids) or None
123128
124    def _simulate_one_iteration_of_trick_or_treat(self):129    def _simulate_one_iteration_of_trick_or_treat(self):
125        """Simulate one cycle of Kids taking Candy from Hosts.130        """Simulate one cycle of Kids taking Candy from Hosts.
126131
127        Return the Kids that are critical after the Cycle or132        Return the Kids that are critical after the Cycle or
128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or133        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
129        an empty List if there are no critical Kids after the Cycle.134        an empty List if there are no critical Kids after the Cycle.
130        """135        """
131136
132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))137        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
133        none_critical_kids_sorted_by_initiative = sorted(138        none_critical_kids_sorted_by_initiative = sorted(
134            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),139            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
135            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True140            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
136        )141        )
137142
138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:143        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
139            return None144            return None
140145
141        critical_kids = []146        critical_kids = []
142        for kid in none_critical_kids_sorted_by_initiative:147        for kid in none_critical_kids_sorted_by_initiative:
143            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)148            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
144            kid.set_position(min_dist_host.get_position())149            kid.set_position(min_dist_host.get_position())
145150
146            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)151            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
147            kid.add_candy(removed_candy)152            kid.add_candy(removed_candy)
148153
149            if kid.is_critical():154            if kid.is_critical():
150                critical_kids.append(kid)155                critical_kids.append(kid)
151156
152        return critical_kids157        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
t107        self.__fill_participants(participants)t107        self._fill_participants(participants)
108108
109    def _fill_participants(self, participants: set):109    def _fill_participants(self, participants: set):
110        for participant in participants:110        for participant in participants:
111            if type(participant) is Kid:111            if type(participant) is Kid:
112                self._kids.append(participant)112                self._kids.append(participant)
113            else:113            else:
114                self._hosts.append(participant)114                self._hosts.append(participant)
115115
116    def get_victim(self):116    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""117        """Simulate a Halloween night and return the first Kids that are critical."""
118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
119            if critical_kids is None:119            if critical_kids is None:
120                return None120                return None
121121
122        return set(critical_kids) or None122        return set(critical_kids) or None
123123
124    def _simulate_one_iteration_of_trick_or_treat(self):124    def _simulate_one_iteration_of_trick_or_treat(self):
125        """Simulate one cycle of Kids taking Candy from Hosts.125        """Simulate one cycle of Kids taking Candy from Hosts.
126126
127        Return the Kids that are critical after the Cycle or127        Return the Kids that are critical after the Cycle or
128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
129        an empty List if there are no critical Kids after the Cycle.129        an empty List if there are no critical Kids after the Cycle.
130        """130        """
131131
132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
133        none_critical_kids_sorted_by_initiative = sorted(133        none_critical_kids_sorted_by_initiative = sorted(
134            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),134            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
135            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True135            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
136        )136        )
137137
138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
139            return None139            return None
140140
141        critical_kids = []141        critical_kids = []
142        for kid in none_critical_kids_sorted_by_initiative:142        for kid in none_critical_kids_sorted_by_initiative:
143            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)143            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
144            kid.set_position(min_dist_host.get_position())144            kid.set_position(min_dist_host.get_position())
145145
146            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)146            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
147            kid.add_candy(removed_candy)147            kid.add_candy(removed_candy)
148148
149            if kid.is_critical():149            if kid.is_critical():
150                critical_kids.append(kid)150                critical_kids.append(kid)
151151
152        return critical_kids152        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
107        self.__fill_participants(participants)107        self.__fill_participants(participants)
108108
n109    def __fill_participants(self, participants: set):n109    def _fill_participants(self, participants: set):
110        for participant in participants:110        for participant in participants:
111            if type(participant) is Kid:111            if type(participant) is Kid:
112                self._kids.append(participant)112                self._kids.append(participant)
113            else:113            else:
114                self._hosts.append(participant)114                self._hosts.append(participant)
115115
116    def get_victim(self):116    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""117        """Simulate a Halloween night and return the first Kids that are critical."""
118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
119            if critical_kids is None:119            if critical_kids is None:
120                return None120                return None
121121
122        return set(critical_kids) or None122        return set(critical_kids) or None
123123
124    def _simulate_one_iteration_of_trick_or_treat(self):124    def _simulate_one_iteration_of_trick_or_treat(self):
125        """Simulate one cycle of Kids taking Candy from Hosts.125        """Simulate one cycle of Kids taking Candy from Hosts.
126126
127        Return the Kids that are critical after the Cycle or127        Return the Kids that are critical after the Cycle or
128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
129        an empty List if there are no critical Kids after the Cycle.129        an empty List if there are no critical Kids after the Cycle.
130        """130        """
131131
132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
133        none_critical_kids_sorted_by_initiative = sorted(133        none_critical_kids_sorted_by_initiative = sorted(
134            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),134            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
135            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True135            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
136        )136        )
137137
138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
139            return None139            return None
140140
141        critical_kids = []141        critical_kids = []
142        for kid in none_critical_kids_sorted_by_initiative:142        for kid in none_critical_kids_sorted_by_initiative:
143            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)143            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
tt144            kid.set_position(min_dist_host.get_position())
145 
144            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)146            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
145            kid.add_candy(removed_candy)147            kid.add_candy(removed_candy)
146148
147            if kid.is_critical():149            if kid.is_critical():
148                critical_kids.append(kid)150                critical_kids.append(kid)
149151
150        return critical_kids152        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
107        self.__fill_participants(participants)107        self.__fill_participants(participants)
108108
109    def __fill_participants(self, participants: set):109    def __fill_participants(self, participants: set):
110        for participant in participants:110        for participant in participants:
111            if type(participant) is Kid:111            if type(participant) is Kid:
112                self._kids.append(participant)112                self._kids.append(participant)
113            else:113            else:
114                self._hosts.append(participant)114                self._hosts.append(participant)
115115
116    def get_victim(self):116    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""117        """Simulate a Halloween night and return the first Kids that are critical."""
118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
119            if critical_kids is None:119            if critical_kids is None:
120                return None120                return None
121121
122        return set(critical_kids) or None122        return set(critical_kids) or None
123123
124    def _simulate_one_iteration_of_trick_or_treat(self):124    def _simulate_one_iteration_of_trick_or_treat(self):
125        """Simulate one cycle of Kids taking Candy from Hosts.125        """Simulate one cycle of Kids taking Candy from Hosts.
126126
127        Return the Kids that are critical after the Cycle or127        Return the Kids that are critical after the Cycle or
128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
129        an empty List if there are no critical Kids after the Cycle.129        an empty List if there are no critical Kids after the Cycle.
130        """130        """
131131
132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
n133        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))n133        none_critical_kids_sorted_by_initiative = sorted(
134            filter(lambda curr_kid: not curr_kid.is_critical(), self._kids),
135            key=lambda curr_kid: curr_kid.get_initiative(), reverse=True
136        )
134137
135        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
136            return None139            return None
n137 n
138        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
139140
140        critical_kids = []141        critical_kids = []
141        for kid in none_critical_kids_sorted_by_initiative:142        for kid in none_critical_kids_sorted_by_initiative:
142            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)143            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
143            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)144            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
t144 t
145            kid.add_candy(removed_candy)145            kid.add_candy(removed_candy)
146146
147            if kid.is_critical():147            if kid.is_critical():
148                critical_kids.append(kid)148                critical_kids.append(kid)
149149
150        return critical_kids150        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
107        self.__fill_participants(participants)107        self.__fill_participants(participants)
108108
109    def __fill_participants(self, participants: set):109    def __fill_participants(self, participants: set):
110        for participant in participants:110        for participant in participants:
111            if type(participant) is Kid:111            if type(participant) is Kid:
112                self._kids.append(participant)112                self._kids.append(participant)
113            else:113            else:
114                self._hosts.append(participant)114                self._hosts.append(participant)
115115
116    def get_victim(self):116    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""117        """Simulate a Halloween night and return the first Kids that are critical."""
118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
119            if critical_kids is None:119            if critical_kids is None:
120                return None120                return None
121121
122        return set(critical_kids) or None122        return set(critical_kids) or None
123123
124    def _simulate_one_iteration_of_trick_or_treat(self):124    def _simulate_one_iteration_of_trick_or_treat(self):
125        """Simulate one cycle of Kids taking Candy from Hosts.125        """Simulate one cycle of Kids taking Candy from Hosts.
126126
127        Return the Kids that are critical after the Cycle or127        Return the Kids that are critical after the Cycle or
128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
129        an empty List if there are no critical Kids after the Cycle.129        an empty List if there are no critical Kids after the Cycle.
130        """130        """
131131
n132        """Filter out Hosts with no Candies."""n
133        hosts_with_candies = filter(lambda curr_host: curr_host.is_basket_empty(), self._hosts)132        hosts_with_candies = list(filter(lambda curr_host: not curr_host.is_basket_empty(), self._hosts))
134        """Filter out critical Kids."""
135        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))133        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))
136134
n137        """If any are empty, return None. The Simulation is over."""n
138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:135        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
139            return None136            return None
140137
t141        """Sort the Kids by Initiative."""t
142        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)138        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
143139
144        critical_kids = []140        critical_kids = []
145        for kid in none_critical_kids_sorted_by_initiative:141        for kid in none_critical_kids_sorted_by_initiative:
146            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)142            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
147            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)143            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
148144
149            kid.add_candy(removed_candy)145            kid.add_candy(removed_candy)
150146
151            if kid.is_critical():147            if kid.is_critical():
152                critical_kids.append(kid)148                critical_kids.append(kid)
153149
154        return critical_kids150        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
107        self.__fill_participants(participants)107        self.__fill_participants(participants)
108108
109    def __fill_participants(self, participants: set):109    def __fill_participants(self, participants: set):
110        for participant in participants:110        for participant in participants:
111            if type(participant) is Kid:111            if type(participant) is Kid:
112                self._kids.append(participant)112                self._kids.append(participant)
113            else:113            else:
114                self._hosts.append(participant)114                self._hosts.append(participant)
115115
116    def get_victim(self):116    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""117        """Simulate a Halloween night and return the first Kids that are critical."""
n118        while True:n
119            critical_kids = self._simulate_one_iteration_of_trick_or_treat()118        while not (critical_kids := self._simulate_one_iteration_of_trick_or_treat()):
120 
121            if critical_kids is None:119            if critical_kids is None:
122                return None120                return None
t123            elif critical_kids:t
124                break
125121
126        return set(critical_kids) or None122        return set(critical_kids) or None
127123
128    def _simulate_one_iteration_of_trick_or_treat(self):124    def _simulate_one_iteration_of_trick_or_treat(self):
129        """Simulate one cycle of Kids taking Candy from Hosts.125        """Simulate one cycle of Kids taking Candy from Hosts.
130126
131        Return the Kids that are critical after the Cycle or127        Return the Kids that are critical after the Cycle or
132        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or128        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
133        an empty List if there are no critical Kids after the Cycle.129        an empty List if there are no critical Kids after the Cycle.
134        """130        """
135131
136        """Filter out Hosts with no Candies."""132        """Filter out Hosts with no Candies."""
137        hosts_with_candies = filter(lambda curr_host: curr_host.is_basket_empty(), self._hosts)133        hosts_with_candies = filter(lambda curr_host: curr_host.is_basket_empty(), self._hosts)
138        """Filter out critical Kids."""134        """Filter out critical Kids."""
139        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))135        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))
140136
141        """If any are empty, return None. The Simulation is over."""137        """If any are empty, return None. The Simulation is over."""
142        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:138        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
143            return None139            return None
144140
145        """Sort the Kids by Initiative."""141        """Sort the Kids by Initiative."""
146        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)142        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
147143
148        critical_kids = []144        critical_kids = []
149        for kid in none_critical_kids_sorted_by_initiative:145        for kid in none_critical_kids_sorted_by_initiative:
150            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)146            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
151            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)147            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
152148
153            kid.add_candy(removed_candy)149            kid.add_candy(removed_candy)
154150
155            if kid.is_critical():151            if kid.is_critical():
156                critical_kids.append(kid)152                critical_kids.append(kid)
157153
158        return critical_kids154        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
48    def is_basket_empty(self):48    def is_basket_empty(self):
49        """Return true if the Basket is empty."""49        """Return true if the Basket is empty."""
50        return not self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
107        self.__fill_participants(participants)107        self.__fill_participants(participants)
108108
109    def __fill_participants(self, participants: set):109    def __fill_participants(self, participants: set):
110        for participant in participants:110        for participant in participants:
111            if type(participant) is Kid:111            if type(participant) is Kid:
112                self._kids.append(participant)112                self._kids.append(participant)
113            else:113            else:
114                self._hosts.append(participant)114                self._hosts.append(participant)
115115
116    def get_victim(self):116    def get_victim(self):
117        """Simulate a Halloween night and return the first Kids that are critical."""117        """Simulate a Halloween night and return the first Kids that are critical."""
118        while True:118        while True:
119            critical_kids = self._simulate_one_iteration_of_trick_or_treat()119            critical_kids = self._simulate_one_iteration_of_trick_or_treat()
120120
121            if critical_kids is None:121            if critical_kids is None:
122                return None122                return None
123            elif critical_kids:123            elif critical_kids:
124                break124                break
125125
126        return set(critical_kids) or None126        return set(critical_kids) or None
127127
128    def _simulate_one_iteration_of_trick_or_treat(self):128    def _simulate_one_iteration_of_trick_or_treat(self):
t129        """Simulate one cycle of Kids taking Candy from Hosts and return the Critical Kids after the cycle."""t129        """Simulate one cycle of Kids taking Candy from Hosts.
130 
131        Return the Kids that are critical after the Cycle or
132        None if the there are no more Kids or Hosts with Candy (The Simulation is over) or
133        an empty List if there are no critical Kids after the Cycle.
134        """
130135
131        """Filter out Hosts with no Candies."""136        """Filter out Hosts with no Candies."""
132        hosts_with_candies = filter(lambda curr_host: curr_host.is_basket_empty(), self._hosts)137        hosts_with_candies = filter(lambda curr_host: curr_host.is_basket_empty(), self._hosts)
133        """Filter out critical Kids."""138        """Filter out critical Kids."""
134        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))139        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))
135140
136        """If any are empty, return None. The Simulation is over."""141        """If any are empty, return None. The Simulation is over."""
137        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:142        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
138            return None143            return None
139144
140        """Sort the Kids by Initiative."""145        """Sort the Kids by Initiative."""
141        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)146        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
142147
143        critical_kids = []148        critical_kids = []
144        for kid in none_critical_kids_sorted_by_initiative:149        for kid in none_critical_kids_sorted_by_initiative:
145            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)150            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
146            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)151            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
147152
148            kid.add_candy(removed_candy)153            kid.add_candy(removed_candy)
149154
150            if kid.is_critical():155            if kid.is_critical():
151                critical_kids.append(kid)156                critical_kids.append(kid)
152157
153        return critical_kids158        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass(candies: list):f1def max_candy_by_mass(candies: list):
2    """Return the Candy with the most Mass."""2    """Return the Candy with the most Mass."""
3    return max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
44
55
6def get_host_with_min_distance(kid, hosts):6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
99
1010
11class Candy:11class Candy:
12    """A Class that represents a Candy."""12    """A Class that represents a Candy."""
1313
14    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
15        self._mass = mass15        self._mass = mass
16        self._uranium = uranium16        self._uranium = uranium
1717
18    def get_mass(self):18    def get_mass(self):
19        """Return the Mass of the Candy."""19        """Return the Mass of the Candy."""
20        return self._mass20        return self._mass
2121
22    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
23        """Return the total Amount of Uranium in the Candy."""23        """Return the total Amount of Uranium in the Candy."""
24        return self._mass * self._uranium24        return self._mass * self._uranium
2525
2626
27class Person:27class Person:
28    """A Class that Represents a Person."""28    """A Class that Represents a Person."""
2929
30    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
31        self._position = None31        self._position = None
32        self.set_position(position)32        self.set_position(position)
33        self._basket = []33        self._basket = []
3434
35    def get_position(self):35    def get_position(self):
36        """Return the Position of the Person."""36        """Return the Position of the Person."""
37        return self._position37        return self._position
3838
39    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
40        """Change the Position of the Person."""40        """Change the Position of the Person."""
41        self._position = position41        self._position = position
4242
43    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
44        """Return the Distance from the current Person to the passed in Person."""44        """Return the Distance from the current Person to the passed in Person."""
45        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
46                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4747
n48    def get_basket(self):n48    def is_basket_empty(self):
49        """Return the Basket of the Person."""49        """Return true if the Basket is empty."""
50        return self._basket50        return not self._basket
5151
52    def __repr__(self):52    def __repr__(self):
53        return f'{self._position}'53        return f'{self._position}'
5454
5555
56class Kid(Person):56class Kid(Person):
57    """A Class that represents a Kid."""57    """A Class that represents a Kid."""
5858
59    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
6060
61    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
62        super().__init__(position)62        super().__init__(position)
63        self._initiative = initiative63        self._initiative = initiative
6464
65    def get_initiative(self):65    def get_initiative(self):
66        """Return the Initiative of the Kid."""66        """Return the Initiative of the Kid."""
67        return self._initiative67        return self._initiative
6868
69    def add_candy(self, candy: Candy or None):69    def add_candy(self, candy: Candy or None):
70        """Add a Candy to the Basket."""70        """Add a Candy to the Basket."""
71        if not candy:71        if not candy:
72            return72            return
7373
74        self._basket.append(candy)74        self._basket.append(candy)
7575
76    def is_critical(self):76    def is_critical(self):
77        """Return true if the Uranium Amount in the Basket is more than 20g."""77        """Return true if the Uranium Amount in the Basket is more than 20g."""
78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7979
80    def __repr__(self):80    def __repr__(self):
81        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
8282
8383
84class Host(Person):84class Host(Person):
85    """A Class that represents a Host."""85    """A Class that represents a Host."""
8686
87    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
88        super().__init__(position)88        super().__init__(position)
89        self._basket = candies[:]89        self._basket = candies[:]
9090
91    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
92        """Select a Candy from the Basket based on the passed in Function."""92        """Select a Candy from the Basket based on the passed in Function."""
93        if not self._basket:93        if not self._basket:
94            return None94            return None
9595
96        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
97        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
98        return chosen_candy or None98        return chosen_candy or None
9999
100100
101class FluxCapacitor:101class FluxCapacitor:
102    """Class that represents a simulation of a Halloween night."""102    """Class that represents a simulation of a Halloween night."""
103103
104    def __init__(self, participants: set):104    def __init__(self, participants: set):
105        self._kids = []105        self._kids = []
106        self._hosts = []106        self._hosts = []
107        self.__fill_participants(participants)107        self.__fill_participants(participants)
n108        self._all_critical_kids = []n
109108
110    def __fill_participants(self, participants: set):109    def __fill_participants(self, participants: set):
111        for participant in participants:110        for participant in participants:
112            if type(participant) is Kid:111            if type(participant) is Kid:
113                self._kids.append(participant)112                self._kids.append(participant)
114            else:113            else:
115                self._hosts.append(participant)114                self._hosts.append(participant)
116115
117    def get_victim(self):116    def get_victim(self):
n118        """Simulate a Halloween night and return the Kids who have the most Uranium."""n117        """Simulate a Halloween night and return the first Kids that arcritical."""
119        hosts_with_candies = filter(lambda x: not not x.get_basket(), self._hosts)118        while True:
119            critical_kids = self._simulate_one_iteration_of_trick_or_treat()
120120
n121        kids_sorted_by_initiative = self._kids[:]n121            if critical_kids is None:
122                return None
123            elif critical_kids:
124                break
125 
126        return set(critical_kids) or None
127 
128    def _simulate_one_iteration_of_trick_or_treat(self):
129        """Simulate one cycle of Kids taking Candy from Hosts and return the Critical Kids after the cycle."""
130 
131        """Filter out Hosts with no Candies."""
132        hosts_with_candies = filter(lambda curr_host: curr_host.is_basket_empty(), self._hosts)
133        """Filter out critical Kids."""
134        none_critical_kids_sorted_by_initiative = list(filter(lambda curr_kid: not curr_kid.is_critical(), self._kids))
135 
136        """If any are empty, return None. The Simulation is over."""
137        if not none_critical_kids_sorted_by_initiative or not hosts_with_candies:
138            return None
139 
140        """Sort the Kids by Initiative."""
122        kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)141        none_critical_kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
123142
124        critical_kids = []143        critical_kids = []
n125        for kid in kids_sorted_by_initiative:n144        for kid in none_critical_kids_sorted_by_initiative:
126            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)145            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
127            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)146            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
128147
129            kid.add_candy(removed_candy)148            kid.add_candy(removed_candy)
130149
131            if kid.is_critical():150            if kid.is_critical():
132                critical_kids.append(kid)151                critical_kids.append(kid)
133152
t134        self._all_critical_kids.extend(critical_kids)t
135 
136        return self._all_critical_kids or None153        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

n1def max_candy_by_mass_lambda():n1def max_candy_by_mass(candies: list):
2    """Return a Lambda Function that returns the Candy with the most Mass"""2    """Return the Candy with the most Mass."""
3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())3    return max(candies, key=lambda candy: candy.get_mass())
4 
5 
6def get_host_with_min_distance(kid, hosts):
7    """Return the Host with the least Distance to the Kid."""
8    return min(hosts, key=lambda host: host.get_distance_to_person(kid))
49
510
6class Candy:11class Candy:
n7    """A Class that represents a Candy"""n12    """A Class that represents a Candy."""
813
9    def __init__(self, mass: float, uranium: float):14    def __init__(self, mass: float, uranium: float):
10        self._mass = mass15        self._mass = mass
11        self._uranium = uranium16        self._uranium = uranium
1217
13    def get_mass(self):18    def get_mass(self):
n14        """Return the Mass of the Candy"""n19        """Return the Mass of the Candy."""
15        return self._mass20        return self._mass
1621
17    def get_uranium_quantity(self):22    def get_uranium_quantity(self):
n18        """Return the total Amount of Uranium in the Candy"""n23        """Return the total Amount of Uranium in the Candy."""
19        return self._mass * self._uranium24        return self._mass * self._uranium
2025
2126
22class Person:27class Person:
n23    """A Class that Represents a Person"""n28    """A Class that Represents a Person."""
2429
25    def __init__(self, position: tuple):30    def __init__(self, position: tuple):
26        self._position = None31        self._position = None
27        self.set_position(position)32        self.set_position(position)
28        self._basket = []33        self._basket = []
2934
30    def get_position(self):35    def get_position(self):
n31        """Return the Position of the Person"""n36        """Return the Position of the Person."""
32        return self._position37        return self._position
3338
34    def set_position(self, position: tuple):39    def set_position(self, position: tuple):
n35        """Change the Position of the Person"""n40        """Change the Position of the Person."""
36        self._position = position41        self._position = position
3742
38    def get_distance_to_person(self, person):43    def get_distance_to_person(self, person):
n39        """Return the Distance from the current Person to the passed in Person"""n44        """Return the Distance from the current Person to the passed in Person."""
40        return ((self._position[0] - person.get_position()[0]) ** 2 + (45        return ((self._position[0] - person.get_position()[0]) ** 2 + (
41                self._position[1] - person.get_position()[1]) ** 2) ** 0.546                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
nn47 
48    def get_basket(self):
49        """Return the Basket of the Person."""
50        return self._basket
4251
43    def __repr__(self):52    def __repr__(self):
44        return f'{self._position}'53        return f'{self._position}'
4554
n46    def __getitem__(self, item):n
47        if isinstance(item, Person):
48            return self.get_distance_to_person(item)
49 
50        return self._position[item]
51 
5255
53class Kid(Person):56class Kid(Person):
n54    """A Class that represents a Kid"""n57    """A Class that represents a Kid."""
5558
56    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2059    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5760
58    def __init__(self, position: tuple, initiative: int):61    def __init__(self, position: tuple, initiative: int):
59        super().__init__(position)62        super().__init__(position)
60        self._initiative = initiative63        self._initiative = initiative
6164
62    def get_initiative(self):65    def get_initiative(self):
n63        """Return the Initiative of the Kid"""n66        """Return the Initiative of the Kid."""
64        return self._initiative67        return self._initiative
6568
n66    def add_candy(self, candy: Candy):n69    def add_candy(self, candy: Candy or None):
67        """Add a Candy to the Basket"""70        """Add a Candy to the Basket."""
71        if not candy:
72            return
73 
68        self._basket.append(candy)74        self._basket.append(candy)
6975
70    def is_critical(self):76    def is_critical(self):
n71        """Return true if the Uranium Amount in the Basket is more than 20g"""n77        """Return true if the Uranium Amount in the Basket is more than 20g."""
72        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS78        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7379
74    def __repr__(self):80    def __repr__(self):
75        return f'{super().__repr__()} : {self._initiative}'81        return f'{super().__repr__()} : {self._initiative}'
7682
7783
78class Host(Person):84class Host(Person):
n79    """A Class that represents a Host"""n85    """A Class that represents a Host."""
8086
81    def __init__(self, position: tuple, candies: list):87    def __init__(self, position: tuple, candies: list):
82        super().__init__(position)88        super().__init__(position)
83        self._basket = candies[:]89        self._basket = candies[:]
8490
85    def remove_candy(self, candy_choosing_function):91    def remove_candy(self, candy_choosing_function):
n86        """Select a Candy from the Basket based on the passed in Function"""n92        """Select a Candy from the Basket based on the passed in Function."""
87        if not self._basket:93        if not self._basket:
88            return None94            return None
8995
90        chosen_candy = candy_choosing_function(self._basket)96        chosen_candy = candy_choosing_function(self._basket)
n91 n
92        self._basket.remove(chosen_candy)97        self._basket.remove(chosen_candy)
n93 n
94        return chosen_candy if chosen_candy else None98        return chosen_candy or None
9599
96100
97class FluxCapacitor:101class FluxCapacitor:
n98    """Class that represents a simulation of a Halloween night"""n102    """Class that represents a simulation of a Halloween night."""
99103
100    def __init__(self, participants: set):104    def __init__(self, participants: set):
101        self._kids = []105        self._kids = []
102        self._hosts = []106        self._hosts = []
103        self.__fill_participants(participants)107        self.__fill_participants(participants)
nn108        self._all_critical_kids = []
104109
105    def __fill_participants(self, participants: set):110    def __fill_participants(self, participants: set):
n106        [n
107            self._kids.append(participant) if type(participant) is Kid
108            else self._hosts.append(participant)
109            for participant in participants111        for participant in participants:
110        ]112            if type(participant) is Kid:
113                self._kids.append(participant)
114            else:
115                self._hosts.append(participant)
111116
112    def get_victim(self):117    def get_victim(self):
n113        """Simulate a Halloween night and return the Kids who have the most Uranium"""n118        """Simulate a Halloween night and return the Kids who have the most Uranium."""
114        sorted_kids = self._kids[:]119        hosts_with_candies = filter(lambda x: not not x.get_basket(), self._hosts)
115        sorted_hosts = self._hosts[:]
116120
nn121        kids_sorted_by_initiative = self._kids[:]
117        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)122        kids_sorted_by_initiative.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
118123
119        critical_kids = []124        critical_kids = []
n120        for kid in sorted_kids:n125        for kid in kids_sorted_by_initiative:
121            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))126            min_dist_host = get_host_with_min_distance(kid, hosts_with_candies)
122            for host in sorted_hosts:
123                removed_candy = host.remove_candy(max_candy_by_mass_lambda())127            removed_candy = min_dist_host.remove_candy(max_candy_by_mass)
124128
n125                if removed_candy:n
126                    kid.add_candy(removed_candy)129            kid.add_candy(removed_candy)
127130
n128                if kid.is_critical():n131            if kid.is_critical():
129                    critical_kids.append(kid)132                critical_kids.append(kid)
130                    break
131133
t132        return critical_kids if critical_kids else Nonet134        self._all_critical_kids.extend(critical_kids)
135 
136        return self._all_critical_kids or None
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass_lambda():f1def max_candy_by_mass_lambda():
2    """Return a Lambda Function that returns the Candy with the most Mass"""2    """Return a Lambda Function that returns the Candy with the most Mass"""
3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())
44
55
6class Candy:6class Candy:
7    """A Class that represents a Candy"""7    """A Class that represents a Candy"""
88
9    def __init__(self, mass: float, uranium: float):9    def __init__(self, mass: float, uranium: float):
10        self._mass = mass10        self._mass = mass
11        self._uranium = uranium11        self._uranium = uranium
1212
13    def get_mass(self):13    def get_mass(self):
14        """Return the Mass of the Candy"""14        """Return the Mass of the Candy"""
15        return self._mass15        return self._mass
1616
17    def get_uranium_quantity(self):17    def get_uranium_quantity(self):
18        """Return the total Amount of Uranium in the Candy"""18        """Return the total Amount of Uranium in the Candy"""
19        return self._mass * self._uranium19        return self._mass * self._uranium
2020
2121
22class Person:22class Person:
23    """A Class that Represents a Person"""23    """A Class that Represents a Person"""
2424
25    def __init__(self, position: tuple):25    def __init__(self, position: tuple):
26        self._position = None26        self._position = None
27        self.set_position(position)27        self.set_position(position)
28        self._basket = []28        self._basket = []
2929
30    def get_position(self):30    def get_position(self):
31        """Return the Position of the Person"""31        """Return the Position of the Person"""
32        return self._position32        return self._position
3333
34    def set_position(self, position: tuple):34    def set_position(self, position: tuple):
35        """Change the Position of the Person"""35        """Change the Position of the Person"""
36        self._position = position36        self._position = position
3737
38    def get_distance_to_person(self, person):38    def get_distance_to_person(self, person):
39        """Return the Distance from the current Person to the passed in Person"""39        """Return the Distance from the current Person to the passed in Person"""
40        return ((self._position[0] - person.get_position()[0]) ** 2 + (40        return ((self._position[0] - person.get_position()[0]) ** 2 + (
41                self._position[1] - person.get_position()[1]) ** 2) ** 0.541                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4242
43    def __repr__(self):43    def __repr__(self):
44        return f'{self._position}'44        return f'{self._position}'
4545
46    def __getitem__(self, item):46    def __getitem__(self, item):
47        if isinstance(item, Person):47        if isinstance(item, Person):
48            return self.get_distance_to_person(item)48            return self.get_distance_to_person(item)
4949
50        return self._position[item]50        return self._position[item]
5151
5252
53class Kid(Person):53class Kid(Person):
54    """A Class that represents a Kid"""54    """A Class that represents a Kid"""
5555
56    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2056    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5757
58    def __init__(self, position: tuple, initiative: int):58    def __init__(self, position: tuple, initiative: int):
59        super().__init__(position)59        super().__init__(position)
60        self._initiative = initiative60        self._initiative = initiative
6161
62    def get_initiative(self):62    def get_initiative(self):
63        """Return the Initiative of the Kid"""63        """Return the Initiative of the Kid"""
64        return self._initiative64        return self._initiative
6565
66    def add_candy(self, candy: Candy):66    def add_candy(self, candy: Candy):
67        """Add a Candy to the Basket"""67        """Add a Candy to the Basket"""
68        self._basket.append(candy)68        self._basket.append(candy)
6969
70    def is_critical(self):70    def is_critical(self):
71        """Return true if the Uranium Amount in the Basket is more than 20g"""71        """Return true if the Uranium Amount in the Basket is more than 20g"""
72        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS72        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7373
74    def __repr__(self):74    def __repr__(self):
75        return f'{super().__repr__()} : {self._initiative}'75        return f'{super().__repr__()} : {self._initiative}'
7676
7777
78class Host(Person):78class Host(Person):
79    """A Class that represents a Host"""79    """A Class that represents a Host"""
8080
81    def __init__(self, position: tuple, candies: list):81    def __init__(self, position: tuple, candies: list):
82        super().__init__(position)82        super().__init__(position)
83        self._basket = candies[:]83        self._basket = candies[:]
8484
85    def remove_candy(self, candy_choosing_function):85    def remove_candy(self, candy_choosing_function):
86        """Select a Candy from the Basket based on the passed in Function"""86        """Select a Candy from the Basket based on the passed in Function"""
87        if not self._basket:87        if not self._basket:
88            return None88            return None
8989
90        chosen_candy = candy_choosing_function(self._basket)90        chosen_candy = candy_choosing_function(self._basket)
9191
92        self._basket.remove(chosen_candy)92        self._basket.remove(chosen_candy)
9393
94        return chosen_candy if chosen_candy else None94        return chosen_candy if chosen_candy else None
9595
9696
97class FluxCapacitor:97class FluxCapacitor:
98    """Class that represents a simulation of a Halloween night"""98    """Class that represents a simulation of a Halloween night"""
9999
100    def __init__(self, participants: set):100    def __init__(self, participants: set):
101        self._kids = []101        self._kids = []
102        self._hosts = []102        self._hosts = []
103        self.__fill_participants(participants)103        self.__fill_participants(participants)
104104
105    def __fill_participants(self, participants: set):105    def __fill_participants(self, participants: set):
106        [106        [
107            self._kids.append(participant) if type(participant) is Kid107            self._kids.append(participant) if type(participant) is Kid
108            else self._hosts.append(participant)108            else self._hosts.append(participant)
109            for participant in participants109            for participant in participants
110        ]110        ]
111111
112    def get_victim(self):112    def get_victim(self):
113        """Simulate a Halloween night and return the Kids who have the most Uranium"""113        """Simulate a Halloween night and return the Kids who have the most Uranium"""
114        sorted_kids = self._kids[:]114        sorted_kids = self._kids[:]
115        sorted_hosts = self._hosts[:]115        sorted_hosts = self._hosts[:]
116116
117        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)117        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
118118
119        critical_kids = []119        critical_kids = []
120        for kid in sorted_kids:120        for kid in sorted_kids:
121            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))121            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))
122            for host in sorted_hosts:122            for host in sorted_hosts:
123                removed_candy = host.remove_candy(max_candy_by_mass_lambda())123                removed_candy = host.remove_candy(max_candy_by_mass_lambda())
124124
125                if removed_candy:125                if removed_candy:
126                    kid.add_candy(removed_candy)126                    kid.add_candy(removed_candy)
127127
128                if kid.is_critical():128                if kid.is_critical():
129                    critical_kids.append(kid)129                    critical_kids.append(kid)
130                    break130                    break
131131
t132        return critical_kidst132        return critical_kids if critical_kids else None
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass_lambda():f1def max_candy_by_mass_lambda():
2    """Return a Lambda Function that returns the Candy with the most Mass"""2    """Return a Lambda Function that returns the Candy with the most Mass"""
3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())
44
55
6class Candy:6class Candy:
7    """A Class that represents a Candy"""7    """A Class that represents a Candy"""
88
9    def __init__(self, mass: float, uranium: float):9    def __init__(self, mass: float, uranium: float):
10        self._mass = mass10        self._mass = mass
11        self._uranium = uranium11        self._uranium = uranium
1212
13    def get_mass(self):13    def get_mass(self):
14        """Return the Mass of the Candy"""14        """Return the Mass of the Candy"""
15        return self._mass15        return self._mass
1616
17    def get_uranium_quantity(self):17    def get_uranium_quantity(self):
18        """Return the total Amount of Uranium in the Candy"""18        """Return the total Amount of Uranium in the Candy"""
19        return self._mass * self._uranium19        return self._mass * self._uranium
2020
2121
22class Person:22class Person:
23    """A Class that Represents a Person"""23    """A Class that Represents a Person"""
2424
25    def __init__(self, position: tuple):25    def __init__(self, position: tuple):
26        self._position = None26        self._position = None
27        self.set_position(position)27        self.set_position(position)
28        self._basket = []28        self._basket = []
2929
30    def get_position(self):30    def get_position(self):
31        """Return the Position of the Person"""31        """Return the Position of the Person"""
32        return self._position32        return self._position
3333
34    def set_position(self, position: tuple):34    def set_position(self, position: tuple):
35        """Change the Position of the Person"""35        """Change the Position of the Person"""
36        self._position = position36        self._position = position
3737
38    def get_distance_to_person(self, person):38    def get_distance_to_person(self, person):
39        """Return the Distance from the current Person to the passed in Person"""39        """Return the Distance from the current Person to the passed in Person"""
40        return ((self._position[0] - person.get_position()[0]) ** 2 + (40        return ((self._position[0] - person.get_position()[0]) ** 2 + (
41                self._position[1] - person.get_position()[1]) ** 2) ** 0.541                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4242
43    def __repr__(self):43    def __repr__(self):
44        return f'{self._position}'44        return f'{self._position}'
4545
46    def __getitem__(self, item):46    def __getitem__(self, item):
47        if isinstance(item, Person):47        if isinstance(item, Person):
48            return self.get_distance_to_person(item)48            return self.get_distance_to_person(item)
4949
50        return self._position[item]50        return self._position[item]
5151
5252
53class Kid(Person):53class Kid(Person):
54    """A Class that represents a Kid"""54    """A Class that represents a Kid"""
5555
56    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2056    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5757
58    def __init__(self, position: tuple, initiative: int):58    def __init__(self, position: tuple, initiative: int):
59        super().__init__(position)59        super().__init__(position)
60        self._initiative = initiative60        self._initiative = initiative
6161
62    def get_initiative(self):62    def get_initiative(self):
63        """Return the Initiative of the Kid"""63        """Return the Initiative of the Kid"""
64        return self._initiative64        return self._initiative
6565
66    def add_candy(self, candy: Candy):66    def add_candy(self, candy: Candy):
67        """Add a Candy to the Basket"""67        """Add a Candy to the Basket"""
68        self._basket.append(candy)68        self._basket.append(candy)
6969
70    def is_critical(self):70    def is_critical(self):
71        """Return true if the Uranium Amount in the Basket is more than 20g"""71        """Return true if the Uranium Amount in the Basket is more than 20g"""
72        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS72        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7373
74    def __repr__(self):74    def __repr__(self):
75        return f'{super().__repr__()} : {self._initiative}'75        return f'{super().__repr__()} : {self._initiative}'
7676
7777
78class Host(Person):78class Host(Person):
79    """A Class that represents a Host"""79    """A Class that represents a Host"""
8080
81    def __init__(self, position: tuple, candies: list):81    def __init__(self, position: tuple, candies: list):
82        super().__init__(position)82        super().__init__(position)
83        self._basket = candies[:]83        self._basket = candies[:]
8484
85    def remove_candy(self, candy_choosing_function):85    def remove_candy(self, candy_choosing_function):
86        """Select a Candy from the Basket based on the passed in Function"""86        """Select a Candy from the Basket based on the passed in Function"""
87        if not self._basket:87        if not self._basket:
88            return None88            return None
8989
90        chosen_candy = candy_choosing_function(self._basket)90        chosen_candy = candy_choosing_function(self._basket)
9191
92        self._basket.remove(chosen_candy)92        self._basket.remove(chosen_candy)
9393
94        return chosen_candy if chosen_candy else None94        return chosen_candy if chosen_candy else None
9595
9696
97class FluxCapacitor:97class FluxCapacitor:
98    """Class that represents a simulation of a Halloween night"""98    """Class that represents a simulation of a Halloween night"""
9999
100    def __init__(self, participants: set):100    def __init__(self, participants: set):
101        self._kids = []101        self._kids = []
102        self._hosts = []102        self._hosts = []
103        self.__fill_participants(participants)103        self.__fill_participants(participants)
104104
105    def __fill_participants(self, participants: set):105    def __fill_participants(self, participants: set):
106        [106        [
107            self._kids.append(participant) if type(participant) is Kid107            self._kids.append(participant) if type(participant) is Kid
108            else self._hosts.append(participant)108            else self._hosts.append(participant)
109            for participant in participants109            for participant in participants
110        ]110        ]
111111
112    def get_victim(self):112    def get_victim(self):
113        """Simulate a Halloween night and return the Kids who have the most Uranium"""113        """Simulate a Halloween night and return the Kids who have the most Uranium"""
114        sorted_kids = self._kids[:]114        sorted_kids = self._kids[:]
115        sorted_hosts = self._hosts[:]115        sorted_hosts = self._hosts[:]
116116
117        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)117        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
118118
119        critical_kids = []119        critical_kids = []
120        for kid in sorted_kids:120        for kid in sorted_kids:
121            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))121            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))
t122            for host in self._hosts:t122            for host in sorted_hosts:
123                removed_candy = host.remove_candy(max_candy_by_mass_lambda())123                removed_candy = host.remove_candy(max_candy_by_mass_lambda())
124124
125                if removed_candy:125                if removed_candy:
126                    kid.add_candy(removed_candy)126                    kid.add_candy(removed_candy)
127127
128                if kid.is_critical():128                if kid.is_critical():
129                    critical_kids.append(kid)129                    critical_kids.append(kid)
130                    break130                    break
131131
132        return critical_kids132        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass_lambda():f1def max_candy_by_mass_lambda():
2    """Return a Lambda Function that returns the Candy with the most Mass"""2    """Return a Lambda Function that returns the Candy with the most Mass"""
3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())
tt4 
45
5class Candy:6class Candy:
6    """A Class that represents a Candy"""7    """A Class that represents a Candy"""
78
8    def __init__(self, mass: float, uranium: float):9    def __init__(self, mass: float, uranium: float):
9        self._mass = mass10        self._mass = mass
10        self._uranium = uranium11        self._uranium = uranium
1112
12    def get_mass(self):13    def get_mass(self):
13        """Return the Mass of the Candy"""14        """Return the Mass of the Candy"""
14        return self._mass15        return self._mass
1516
16    def get_uranium_quantity(self):17    def get_uranium_quantity(self):
17        """Return the total Amount of Uranium in the Candy"""18        """Return the total Amount of Uranium in the Candy"""
18        return self._mass * self._uranium19        return self._mass * self._uranium
1920
2021
21class Person:22class Person:
22    """A Class that Represents a Person"""23    """A Class that Represents a Person"""
2324
24    def __init__(self, position: tuple):25    def __init__(self, position: tuple):
25        self._position = None26        self._position = None
26        self.set_position(position)27        self.set_position(position)
27        self._basket = []28        self._basket = []
2829
29    def get_position(self):30    def get_position(self):
30        """Return the Position of the Person"""31        """Return the Position of the Person"""
31        return self._position32        return self._position
3233
33    def set_position(self, position: tuple):34    def set_position(self, position: tuple):
34        """Change the Position of the Person"""35        """Change the Position of the Person"""
35        self._position = position36        self._position = position
3637
37    def get_distance_to_person(self, person):38    def get_distance_to_person(self, person):
38        """Return the Distance from the current Person to the passed in Person"""39        """Return the Distance from the current Person to the passed in Person"""
39        return ((self._position[0] - person.get_position()[0]) ** 2 + (40        return ((self._position[0] - person.get_position()[0]) ** 2 + (
40                self._position[1] - person.get_position()[1]) ** 2) ** 0.541                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4142
42    def __repr__(self):43    def __repr__(self):
43        return f'{self._position}'44        return f'{self._position}'
4445
45    def __getitem__(self, item):46    def __getitem__(self, item):
46        if isinstance(item, Person):47        if isinstance(item, Person):
47            return self.get_distance_to_person(item)48            return self.get_distance_to_person(item)
4849
49        return self._position[item]50        return self._position[item]
5051
5152
52class Kid(Person):53class Kid(Person):
53    """A Class that represents a Kid"""54    """A Class that represents a Kid"""
5455
55    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2056    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5657
57    def __init__(self, position: tuple, initiative: int):58    def __init__(self, position: tuple, initiative: int):
58        super().__init__(position)59        super().__init__(position)
59        self._initiative = initiative60        self._initiative = initiative
6061
61    def get_initiative(self):62    def get_initiative(self):
62        """Return the Initiative of the Kid"""63        """Return the Initiative of the Kid"""
63        return self._initiative64        return self._initiative
6465
65    def add_candy(self, candy: Candy):66    def add_candy(self, candy: Candy):
66        """Add a Candy to the Basket"""67        """Add a Candy to the Basket"""
67        self._basket.append(candy)68        self._basket.append(candy)
6869
69    def is_critical(self):70    def is_critical(self):
70        """Return true if the Uranium Amount in the Basket is more than 20g"""71        """Return true if the Uranium Amount in the Basket is more than 20g"""
71        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS72        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7273
73    def __repr__(self):74    def __repr__(self):
74        return f'{super().__repr__()} : {self._initiative}'75        return f'{super().__repr__()} : {self._initiative}'
7576
7677
77class Host(Person):78class Host(Person):
78    """A Class that represents a Host"""79    """A Class that represents a Host"""
7980
80    def __init__(self, position: tuple, candies: list):81    def __init__(self, position: tuple, candies: list):
81        super().__init__(position)82        super().__init__(position)
82        self._basket = candies[:]83        self._basket = candies[:]
8384
84    def remove_candy(self, candy_choosing_function):85    def remove_candy(self, candy_choosing_function):
85        """Select a Candy from the Basket based on the passed in Function"""86        """Select a Candy from the Basket based on the passed in Function"""
86        if not self._basket:87        if not self._basket:
87            return None88            return None
8889
89        chosen_candy = candy_choosing_function(self._basket)90        chosen_candy = candy_choosing_function(self._basket)
9091
91        self._basket.remove(chosen_candy)92        self._basket.remove(chosen_candy)
9293
93        return chosen_candy if chosen_candy else None94        return chosen_candy if chosen_candy else None
9495
9596
96class FluxCapacitor:97class FluxCapacitor:
97    """Class that represents a simulation of a Halloween night"""98    """Class that represents a simulation of a Halloween night"""
9899
99    def __init__(self, participants: set):100    def __init__(self, participants: set):
100        self._kids = []101        self._kids = []
101        self._hosts = []102        self._hosts = []
102        self.__fill_participants(participants)103        self.__fill_participants(participants)
103104
104    def __fill_participants(self, participants: set):105    def __fill_participants(self, participants: set):
105        [106        [
106            self._kids.append(participant) if type(participant) is Kid107            self._kids.append(participant) if type(participant) is Kid
107            else self._hosts.append(participant)108            else self._hosts.append(participant)
108            for participant in participants109            for participant in participants
109        ]110        ]
110111
111    def get_victim(self):112    def get_victim(self):
112        """Simulate a Halloween night and return the Kids who have the most Uranium"""113        """Simulate a Halloween night and return the Kids who have the most Uranium"""
113        sorted_kids = self._kids[:]114        sorted_kids = self._kids[:]
114        sorted_hosts = self._hosts[:]115        sorted_hosts = self._hosts[:]
115116
116        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)117        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
117118
118        critical_kids = []119        critical_kids = []
119        for kid in sorted_kids:120        for kid in sorted_kids:
120            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))121            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))
121            for host in self._hosts:122            for host in self._hosts:
122                removed_candy = host.remove_candy(max_candy_by_mass_lambda())123                removed_candy = host.remove_candy(max_candy_by_mass_lambda())
123124
124                if removed_candy:125                if removed_candy:
125                    kid.add_candy(removed_candy)126                    kid.add_candy(removed_candy)
126127
127                if kid.is_critical():128                if kid.is_critical():
128                    critical_kids.append(kid)129                    critical_kids.append(kid)
129                    break130                    break
130131
131        return critical_kids132        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1def max_candy_by_mass_lambda():f1def max_candy_by_mass_lambda():
2    """Return a Lambda Function that returns the Candy with the most Mass"""2    """Return a Lambda Function that returns the Candy with the most Mass"""
3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())
44
5class Candy:5class Candy:
6    """A Class that represents a Candy"""6    """A Class that represents a Candy"""
77
8    def __init__(self, mass: float, uranium: float):8    def __init__(self, mass: float, uranium: float):
9        self._mass = mass9        self._mass = mass
10        self._uranium = uranium10        self._uranium = uranium
1111
12    def get_mass(self):12    def get_mass(self):
13        """Return the Mass of the Candy"""13        """Return the Mass of the Candy"""
14        return self._mass14        return self._mass
1515
16    def get_uranium_quantity(self):16    def get_uranium_quantity(self):
17        """Return the total Amount of Uranium in the Candy"""17        """Return the total Amount of Uranium in the Candy"""
18        return self._mass * self._uranium18        return self._mass * self._uranium
1919
2020
21class Person:21class Person:
22    """A Class that Represents a Person"""22    """A Class that Represents a Person"""
2323
24    def __init__(self, position: tuple):24    def __init__(self, position: tuple):
25        self._position = None25        self._position = None
26        self.set_position(position)26        self.set_position(position)
27        self._basket = []27        self._basket = []
2828
29    def get_position(self):29    def get_position(self):
30        """Return the Position of the Person"""30        """Return the Position of the Person"""
31        return self._position31        return self._position
3232
33    def set_position(self, position: tuple):33    def set_position(self, position: tuple):
34        """Change the Position of the Person"""34        """Change the Position of the Person"""
35        self._position = position35        self._position = position
3636
37    def get_distance_to_person(self, person):37    def get_distance_to_person(self, person):
38        """Return the Distance from the current Person to the passed in Person"""38        """Return the Distance from the current Person to the passed in Person"""
39        return ((self._position[0] - person.get_position()[0]) ** 2 + (39        return ((self._position[0] - person.get_position()[0]) ** 2 + (
40                self._position[1] - person.get_position()[1]) ** 2) ** 0.540                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
4141
42    def __repr__(self):42    def __repr__(self):
43        return f'{self._position}'43        return f'{self._position}'
4444
45    def __getitem__(self, item):45    def __getitem__(self, item):
46        if isinstance(item, Person):46        if isinstance(item, Person):
47            return self.get_distance_to_person(item)47            return self.get_distance_to_person(item)
4848
49        return self._position[item]49        return self._position[item]
5050
5151
52class Kid(Person):52class Kid(Person):
53    """A Class that represents a Kid"""53    """A Class that represents a Kid"""
5454
55    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2055    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5656
57    def __init__(self, position: tuple, initiative: int):57    def __init__(self, position: tuple, initiative: int):
58        super().__init__(position)58        super().__init__(position)
59        self._initiative = initiative59        self._initiative = initiative
6060
61    def get_initiative(self):61    def get_initiative(self):
62        """Return the Initiative of the Kid"""62        """Return the Initiative of the Kid"""
63        return self._initiative63        return self._initiative
6464
65    def add_candy(self, candy: Candy):65    def add_candy(self, candy: Candy):
66        """Add a Candy to the Basket"""66        """Add a Candy to the Basket"""
67        self._basket.append(candy)67        self._basket.append(candy)
6868
69    def is_critical(self):69    def is_critical(self):
70        """Return true if the Uranium Amount in the Basket is more than 20g"""70        """Return true if the Uranium Amount in the Basket is more than 20g"""
71        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS71        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
7272
73    def __repr__(self):73    def __repr__(self):
74        return f'{super().__repr__()} : {self._initiative}'74        return f'{super().__repr__()} : {self._initiative}'
7575
7676
77class Host(Person):77class Host(Person):
78    """A Class that represents a Host"""78    """A Class that represents a Host"""
7979
80    def __init__(self, position: tuple, candies: list):80    def __init__(self, position: tuple, candies: list):
81        super().__init__(position)81        super().__init__(position)
82        self._basket = candies[:]82        self._basket = candies[:]
8383
84    def remove_candy(self, candy_choosing_function):84    def remove_candy(self, candy_choosing_function):
85        """Select a Candy from the Basket based on the passed in Function"""85        """Select a Candy from the Basket based on the passed in Function"""
86        if not self._basket:86        if not self._basket:
87            return None87            return None
8888
89        chosen_candy = candy_choosing_function(self._basket)89        chosen_candy = candy_choosing_function(self._basket)
9090
91        self._basket.remove(chosen_candy)91        self._basket.remove(chosen_candy)
9292
93        return chosen_candy if chosen_candy else None93        return chosen_candy if chosen_candy else None
9494
9595
96class FluxCapacitor:96class FluxCapacitor:
97    """Class that represents a simulation of a Halloween night"""97    """Class that represents a simulation of a Halloween night"""
9898
99    def __init__(self, participants: set):99    def __init__(self, participants: set):
100        self._kids = []100        self._kids = []
101        self._hosts = []101        self._hosts = []
102        self.__fill_participants(participants)102        self.__fill_participants(participants)
103103
104    def __fill_participants(self, participants: set):104    def __fill_participants(self, participants: set):
105        [105        [
106            self._kids.append(participant) if type(participant) is Kid106            self._kids.append(participant) if type(participant) is Kid
107            else self._hosts.append(participant)107            else self._hosts.append(participant)
108            for participant in participants108            for participant in participants
109        ]109        ]
110110
111    def get_victim(self):111    def get_victim(self):
112        """Simulate a Halloween night and return the Kids who have the most Uranium"""112        """Simulate a Halloween night and return the Kids who have the most Uranium"""
113        sorted_kids = self._kids[:]113        sorted_kids = self._kids[:]
114        sorted_hosts = self._hosts[:]114        sorted_hosts = self._hosts[:]
115115
116        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)116        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
117117
118        critical_kids = []118        critical_kids = []
t119        # for kid in sorted_kids:t119        for kid in sorted_kids:
120        #     sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))120            sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))
121        #     for host in self._hosts:121            for host in self._hosts:
122        #         removed_candy = host.remove_candy(max_candy_by_mass_lambda())122                removed_candy = host.remove_candy(max_candy_by_mass_lambda())
123        #123 
124        #         if removed_candy:124                if removed_candy:
125        #             kid.add_candy(removed_candy)125                    kid.add_candy(removed_candy)
126        #126 
127        #         if kid.is_critical():127                if kid.is_critical():
128        #             critical_kids.append(kid)128                    critical_kids.append(kid)
129        #             break129                    break
130130
131        return critical_kids131        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

nn1def max_candy_by_mass_lambda():
2    """Return a Lambda Function that returns the Candy with the most Mass"""
3    return lambda candies: max(candies, key=lambda candy: candy.get_mass())
4 
1class Candy:5class Candy:
2    """A Class that represents a Candy"""6    """A Class that represents a Candy"""
37
4    def __init__(self, mass: float, uranium: float):8    def __init__(self, mass: float, uranium: float):
5        self._mass = mass9        self._mass = mass
6        self._uranium = uranium10        self._uranium = uranium
711
8    def get_mass(self):12    def get_mass(self):
9        """Return the Mass of the Candy"""13        """Return the Mass of the Candy"""
10        return self._mass14        return self._mass
1115
12    def get_uranium_quantity(self):16    def get_uranium_quantity(self):
13        """Return the total Amount of Uranium in the Candy"""17        """Return the total Amount of Uranium in the Candy"""
14        return self._mass * self._uranium18        return self._mass * self._uranium
1519
1620
17class Person:21class Person:
18    """A Class that Represents a Person"""22    """A Class that Represents a Person"""
1923
20    def __init__(self, position: tuple):24    def __init__(self, position: tuple):
21        self._position = None25        self._position = None
22        self.set_position(position)26        self.set_position(position)
23        self._basket = []27        self._basket = []
2428
25    def get_position(self):29    def get_position(self):
26        """Return the Position of the Person"""30        """Return the Position of the Person"""
27        return self._position31        return self._position
2832
29    def set_position(self, position: tuple):33    def set_position(self, position: tuple):
30        """Change the Position of the Person"""34        """Change the Position of the Person"""
31        self._position = position35        self._position = position
3236
33    def get_distance_to_person(self, person):37    def get_distance_to_person(self, person):
34        """Return the Distance from the current Person to the passed in Person"""38        """Return the Distance from the current Person to the passed in Person"""
35        return ((self._position[0] - person.get_position()[0]) ** 2 + (39        return ((self._position[0] - person.get_position()[0]) ** 2 + (
36                self._position[1] - person.get_position()[1]) ** 2) ** 0.540                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
3741
38    def __repr__(self):42    def __repr__(self):
39        return f'{self._position}'43        return f'{self._position}'
4044
41    def __getitem__(self, item):45    def __getitem__(self, item):
42        if isinstance(item, Person):46        if isinstance(item, Person):
43            return self.get_distance_to_person(item)47            return self.get_distance_to_person(item)
4448
45        return self._position[item]49        return self._position[item]
4650
4751
48class Kid(Person):52class Kid(Person):
49    """A Class that represents a Kid"""53    """A Class that represents a Kid"""
5054
51    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2055    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5256
53    def __init__(self, position: tuple, initiative: int):57    def __init__(self, position: tuple, initiative: int):
54        super().__init__(position)58        super().__init__(position)
55        self._initiative = initiative59        self._initiative = initiative
5660
57    def get_initiative(self):61    def get_initiative(self):
58        """Return the Initiative of the Kid"""62        """Return the Initiative of the Kid"""
59        return self._initiative63        return self._initiative
6064
61    def add_candy(self, candy: Candy):65    def add_candy(self, candy: Candy):
62        """Add a Candy to the Basket"""66        """Add a Candy to the Basket"""
63        self._basket.append(candy)67        self._basket.append(candy)
6468
65    def is_critical(self):69    def is_critical(self):
66        """Return true if the Uranium Amount in the Basket is more than 20g"""70        """Return true if the Uranium Amount in the Basket is more than 20g"""
67        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS71        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
6872
69    def __repr__(self):73    def __repr__(self):
70        return f'{super().__repr__()} : {self._initiative}'74        return f'{super().__repr__()} : {self._initiative}'
7175
7276
73class Host(Person):77class Host(Person):
74    """A Class that represents a Host"""78    """A Class that represents a Host"""
7579
76    def __init__(self, position: tuple, candies: list):80    def __init__(self, position: tuple, candies: list):
77        super().__init__(position)81        super().__init__(position)
78        self._basket = candies[:]82        self._basket = candies[:]
7983
80    def remove_candy(self, candy_choosing_function):84    def remove_candy(self, candy_choosing_function):
81        """Select a Candy from the Basket based on the passed in Function"""85        """Select a Candy from the Basket based on the passed in Function"""
82        if not self._basket:86        if not self._basket:
83            return None87            return None
8488
85        chosen_candy = candy_choosing_function(self._basket)89        chosen_candy = candy_choosing_function(self._basket)
8690
87        self._basket.remove(chosen_candy)91        self._basket.remove(chosen_candy)
8892
n89        return chosen_candyn93        return chosen_candy if chosen_candy else None
9094
9195
92class FluxCapacitor:96class FluxCapacitor:
93    """Class that represents a simulation of a Halloween night"""97    """Class that represents a simulation of a Halloween night"""
9498
95    def __init__(self, participants: set):99    def __init__(self, participants: set):
96        self._kids = []100        self._kids = []
97        self._hosts = []101        self._hosts = []
98        self.__fill_participants(participants)102        self.__fill_participants(participants)
99103
100    def __fill_participants(self, participants: set):104    def __fill_participants(self, participants: set):
101        [105        [
102            self._kids.append(participant) if type(participant) is Kid106            self._kids.append(participant) if type(participant) is Kid
103            else self._hosts.append(participant)107            else self._hosts.append(participant)
104            for participant in participants108            for participant in participants
105        ]109        ]
106110
107    def get_victim(self):111    def get_victim(self):
108        """Simulate a Halloween night and return the Kids who have the most Uranium"""112        """Simulate a Halloween night and return the Kids who have the most Uranium"""
109        sorted_kids = self._kids[:]113        sorted_kids = self._kids[:]
110        sorted_hosts = self._hosts[:]114        sorted_hosts = self._hosts[:]
111115
n112        sorted_kids.sort(key=lambda kid: kid.get_initiative(), reverse=True)n116        sorted_kids.sort(key=lambda curr_kid: curr_kid.get_initiative(), reverse=True)
113117
114        critical_kids = []118        critical_kids = []
t115        for kid in sorted_kids:t119        # for kid in sorted_kids:
116            sorted_hosts.sort(key=lambda h: (h[kid], h[0], h[1]))120        #     sorted_hosts.sort(key=lambda curr_host: (curr_host[kid], curr_host[0], curr_host[1]))
117            for host in self._hosts:121        #     for host in self._hosts:
118                removed_candy = host.remove_candy(lambda x: max(x, key=lambda c: c.get_uranium_quantity()))122        #         removed_candy = host.remove_candy(max_candy_by_mass_lambda())
119 123        #
120                if removed_candy:124        #         if removed_candy:
121                    kid.add_candy(removed_candy)125        #             kid.add_candy(removed_candy)
122 126        #
123                if kid.is_critical():127        #         if kid.is_critical():
124                    critical_kids.append(kid)128        #             critical_kids.append(kid)
125                    break129        #             break
126130
127        return critical_kids131        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Candy:f1class Candy:
2    """A Class that represents a Candy"""2    """A Class that represents a Candy"""
33
4    def __init__(self, mass: float, uranium: float):4    def __init__(self, mass: float, uranium: float):
5        self._mass = mass5        self._mass = mass
6        self._uranium = uranium6        self._uranium = uranium
77
8    def get_mass(self):8    def get_mass(self):
9        """Return the Mass of the Candy"""9        """Return the Mass of the Candy"""
10        return self._mass10        return self._mass
1111
12    def get_uranium_quantity(self):12    def get_uranium_quantity(self):
13        """Return the total Amount of Uranium in the Candy"""13        """Return the total Amount of Uranium in the Candy"""
14        return self._mass * self._uranium14        return self._mass * self._uranium
1515
1616
17class Person:17class Person:
18    """A Class that Represents a Person"""18    """A Class that Represents a Person"""
1919
20    def __init__(self, position: tuple):20    def __init__(self, position: tuple):
21        self._position = None21        self._position = None
22        self.set_position(position)22        self.set_position(position)
23        self._basket = []23        self._basket = []
2424
25    def get_position(self):25    def get_position(self):
26        """Return the Position of the Person"""26        """Return the Position of the Person"""
27        return self._position27        return self._position
2828
29    def set_position(self, position: tuple):29    def set_position(self, position: tuple):
30        """Change the Position of the Person"""30        """Change the Position of the Person"""
31        self._position = position31        self._position = position
3232
33    def get_distance_to_person(self, person):33    def get_distance_to_person(self, person):
34        """Return the Distance from the current Person to the passed in Person"""34        """Return the Distance from the current Person to the passed in Person"""
35        return ((self._position[0] - person.get_position()[0]) ** 2 + (35        return ((self._position[0] - person.get_position()[0]) ** 2 + (
36                self._position[1] - person.get_position()[1]) ** 2) ** 0.536                self._position[1] - person.get_position()[1]) ** 2) ** 0.5
3737
38    def __repr__(self):38    def __repr__(self):
39        return f'{self._position}'39        return f'{self._position}'
4040
41    def __getitem__(self, item):41    def __getitem__(self, item):
42        if isinstance(item, Person):42        if isinstance(item, Person):
43            return self.get_distance_to_person(item)43            return self.get_distance_to_person(item)
4444
45        return self._position[item]45        return self._position[item]
4646
4747
48class Kid(Person):48class Kid(Person):
49    """A Class that represents a Kid"""49    """A Class that represents a Kid"""
5050
51    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 2051    CRITICAL_URANIUM_AMOUNT_IN_GRAMS = 20
5252
53    def __init__(self, position: tuple, initiative: int):53    def __init__(self, position: tuple, initiative: int):
54        super().__init__(position)54        super().__init__(position)
55        self._initiative = initiative55        self._initiative = initiative
5656
57    def get_initiative(self):57    def get_initiative(self):
58        """Return the Initiative of the Kid"""58        """Return the Initiative of the Kid"""
59        return self._initiative59        return self._initiative
6060
61    def add_candy(self, candy: Candy):61    def add_candy(self, candy: Candy):
62        """Add a Candy to the Basket"""62        """Add a Candy to the Basket"""
63        self._basket.append(candy)63        self._basket.append(candy)
6464
65    def is_critical(self):65    def is_critical(self):
66        """Return true if the Uranium Amount in the Basket is more than 20g"""66        """Return true if the Uranium Amount in the Basket is more than 20g"""
67        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS67        return sum([candy.get_uranium_quantity() for candy in self._basket]) > Kid.CRITICAL_URANIUM_AMOUNT_IN_GRAMS
6868
69    def __repr__(self):69    def __repr__(self):
70        return f'{super().__repr__()} : {self._initiative}'70        return f'{super().__repr__()} : {self._initiative}'
7171
7272
73class Host(Person):73class Host(Person):
74    """A Class that represents a Host"""74    """A Class that represents a Host"""
7575
76    def __init__(self, position: tuple, candies: list):76    def __init__(self, position: tuple, candies: list):
77        super().__init__(position)77        super().__init__(position)
78        self._basket = candies[:]78        self._basket = candies[:]
7979
80    def remove_candy(self, candy_choosing_function):80    def remove_candy(self, candy_choosing_function):
81        """Select a Candy from the Basket based on the passed in Function"""81        """Select a Candy from the Basket based on the passed in Function"""
82        if not self._basket:82        if not self._basket:
83            return None83            return None
8484
85        chosen_candy = candy_choosing_function(self._basket)85        chosen_candy = candy_choosing_function(self._basket)
8686
87        self._basket.remove(chosen_candy)87        self._basket.remove(chosen_candy)
8888
89        return chosen_candy89        return chosen_candy
9090
9191
92class FluxCapacitor:92class FluxCapacitor:
93    """Class that represents a simulation of a Halloween night"""93    """Class that represents a simulation of a Halloween night"""
9494
95    def __init__(self, participants: set):95    def __init__(self, participants: set):
96        self._kids = []96        self._kids = []
97        self._hosts = []97        self._hosts = []
98        self.__fill_participants(participants)98        self.__fill_participants(participants)
9999
100    def __fill_participants(self, participants: set):100    def __fill_participants(self, participants: set):
101        [101        [
102            self._kids.append(participant) if type(participant) is Kid102            self._kids.append(participant) if type(participant) is Kid
103            else self._hosts.append(participant)103            else self._hosts.append(participant)
104            for participant in participants104            for participant in participants
105        ]105        ]
106106
107    def get_victim(self):107    def get_victim(self):
108        """Simulate a Halloween night and return the Kids who have the most Uranium"""108        """Simulate a Halloween night and return the Kids who have the most Uranium"""
109        sorted_kids = self._kids[:]109        sorted_kids = self._kids[:]
110        sorted_hosts = self._hosts[:]110        sorted_hosts = self._hosts[:]
111111
112        sorted_kids.sort(key=lambda kid: kid.get_initiative(), reverse=True)112        sorted_kids.sort(key=lambda kid: kid.get_initiative(), reverse=True)
113113
114        critical_kids = []114        critical_kids = []
115        for kid in sorted_kids:115        for kid in sorted_kids:
t116            sorted_hosts.sort(key=lambda h: (h[k1], h[0], h[1]))t116            sorted_hosts.sort(key=lambda h: (h[kid], h[0], h[1]))
117            for host in self._hosts:117            for host in self._hosts:
118                removed_candy = host.remove_candy(lambda x: max(x, key=lambda c: c.get_uranium_quantity()))118                removed_candy = host.remove_candy(lambda x: max(x, key=lambda c: c.get_uranium_quantity()))
119119
120                if removed_candy:120                if removed_candy:
121                    kid.add_candy(removed_candy)121                    kid.add_candy(removed_candy)
122122
123                if kid.is_critical():123                if kid.is_critical():
124                    critical_kids.append(kid)124                    critical_kids.append(kid)
125                    break125                    break
126126
127        return critical_kids127        return critical_kids
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op