1import math
2
3class Candy:
4 def __init__(self, mass, uranium):
5 self.mass = mass
6 self.uranium = uranium
7
8 def get_uranium_quantity(self):
9 return self.mass * self.uranium
10
11 def get_mass(self):
12 return self.mass
13
14
15class Person:
16 def __init__(self, position):
17 self.position = tuple(position)
18
19 def get_position(self):
20 return self.position
21
22 def set_position(self, new_pos):
23 self.position = new_pos
24
25
26class Kid(Person):
27
28 max_uran = 20
29
30 def __init__(self, position, initiative):
31 super().__init__(position)
32 self.initiative = initiative
33 self.uranium_quantity = 0
34 #this is a variable for later, which is useful in class FluxCapacitor
35 self.unvisited_hosts = []
36
37 def get_initiative(self):
38 return self.initiative
39
40 def add_candy(self, candy):
41 self.uranium_quantity += candy.get_uranium_quantity()
42
43 def is_critical(self):
44 if self.uranium_quantity > self.max_uran:
45 return True
46 return False
47
48
49class Host(Person):
50
51 def __init__(self, position, candies):
52 super().__init__(position)
53 self.candies = [Candy(mass, uranium) for mass, uranium in candies]
54
55 def remove_candy(self, func):
56 if len(self.candies) == 0:
57 return None
58 else:
59 chosen_candy = func(self.candies)
60 self.candies.remove(chosen_candy)
61 return chosen_candy
62
63
64class FluxCapacitor:
65
66 def __init__(self, participants):
67 self.participants = participants
68
69 #This is a help function to find the indices
70 #of duplicates in the distances from kid to host list
71 def indices_dup_dist(distances):
72 list_duplicates = set()
73 unique_dict = {}
74 for index, elem in enumerate(distances):
75 if elem not in unique_dict:
76 unique_dict[elem] = index
77 else:
78 list_duplicates.add(unique_dict[elem])
79 list_duplicates.add(index)
80 return list(list_duplicates)
81
82 def get_victim(self):
83 victims = set()
84 self.participants = list(self.participants)
85 #print(self.participants)
86 #this for loop assigns to the kid objects a list of unvisited hosts
87 for kid in self.participants:
88 if isinstance(kid, Kid):
89 kid.unvisited_hosts = [x for x in self.participants
90 if isinstance(x, Host)]
91
92 while not victims:
93 #this for loop sends every kid to its respective host
94 for kid in self.participants:
95 if isinstance(kid, Kid):
96 hosts = [x for x in kid.unvisited_hosts
97 if isinstance(x, Host)]
98 hosts_coord = [x.position for x in hosts]
99 distances = [math.sqrt((x[0] - kid.position[0]) ** 2 +
100 (x[1] - kid.position[1]) ** 2)
101 for x in hosts_coord]
102 closest_host = []
103
104 if len(distances) > len(set(distances)):
105 indices = FluxCapacitor.indices_dup_dist(distances)
106 x_coord = []
107 y_coord = []
108 for index in indices:
109 x_coord.append(hosts_coord[index][0])
110 y_coord.append(hosts_coord[index][1])
111 if len(set(x_coord)) > 1:
112 least_x_val = x_coord.index(min(x_coord))
113 closest_host = hosts[least_x_val]
114 else:
115 least_y_val = y_coord.index(min(y_coord))
116 closest_host = hosts[least_y_val]
117 kid.set_position(closest_host.position)
118 kid.unvisited_hosts.remove(closest_host)
119 continue
120
121 closest_host = hosts[distances.index(min(distances))]
122 kid.set_position(closest_host.position)
123 kid.unvisited_hosts.remove(closest_host)
124
125 #this loop gives every kid candies from the hosts
126 for host in self.participants:
127 if isinstance(host, Host):
128 if len(host.candies) > 0:
129 kids = [x for x in self.participants
130 if isinstance(x, Kid)]
131 kids_at_host = []
132 for kid in kids:
133 if kid.position == host.position:
134 kids_at_host.append(kid)
135 kid_init = []
136
137 for kid in kids_at_host:
138 kid_init.append(kid.initiative)
139
140 while len(kid_init) > 0 and len(host.candies) > 0:
141 kid_index = kid_init.index(max(kid_init))
142 kid = kids_at_host[kid_index]
143 kid.add_candy(host.remove_candy(candy_max_mass))
144 kid_init.pop(kid_index)
145
146 after_loop_kids = [x for x in self.participants if
147 isinstance(x, Kid)]
148
149 kids_ur = [x.is_critical() for x in after_loop_kids]
150
151 #here we add the victims, if there are any, in a set
152 for index, boolean_val in enumerate(kids_ur):
153 if boolean_val == True:
154 victims.add(after_loop_kids[index])
155
156 if len(victims) > 0:
157 break
158
159 for kid in after_loop_kids:
160 if not kid.unvisited_hosts:
161 return None
162 continue
163
164 return victims
165
166
167def candy_max_mass(treats):
168 new_list = [x.get_mass() for x in treats]
169 max_index = new_list.index(max(new_list))
170 return treats[max_index]
.FEF........
======================================================================
ERROR: test_empty_hosts (test.FluxCapacitorTest)
Test with empty hosts.
----------------------------------------------------------------------
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 88, in test_empty_hosts
self.assertEqual(flux_capacitor.get_victim(), None)
File "/tmp/solution.py", line 121, in get_victim
closest_host = hosts[distances.index(min(distances))]
ValueError: min() arg is an empty sequence
======================================================================
FAIL: test_empty (test.FluxCapacitorTest)
Test with empty collection.
----------------------------------------------------------------------
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 80, in test_empty
self.assertEqual(flux_capacitor.get_victim(), None)
File "/tmp/solution.py", line 92, in get_victim
while not victims:
File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 69, in handler
_raise_exception(timeout_exception, exception_message)
File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 45, in _raise_exception
raise exception()
timeout_decorator.timeout_decorator.TimeoutError: 'Timed Out'
======================================================================
FAIL: test_empty_kids (test.FluxCapacitorTest)
Test with empty kids.
----------------------------------------------------------------------
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 96, in test_empty_kids
self.assertEqual(flux_capacitor.get_victim(), None)
File "/tmp/solution.py", line 127, in get_victim
if isinstance(host, Host):
File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 69, in handler
_raise_exception(timeout_exception, exception_message)
File "/usr/local/lib/python3.10/dist-packages/timeout_decorator/timeout_decorator.py", line 45, in _raise_exception
raise exception()
timeout_decorator.timeout_decorator.TimeoutError: 'Timed Out'
----------------------------------------------------------------------
Ran 12 tests in 0.401s
FAILED (failures=2, errors=1)
Георги Кунчев
07.11.2023 11:25Поради проблемите, свързани с безкрайни цикли в някои от тестовете, добавихме подобрение на сайта, така че той вече ще отрази точките на всички останали тестове.
Ако имаш безкраен цикъл за някой тест кейс, той ще касае само него и все пак ще получиш точки за остнаалите си тестове.
|
Георги Кунчев
07.11.2023 08:58Имаш безкраен цикъл, заради който тестовете ни ще зависнат и няма да имаш точки. Моля изтествай с реален случай.
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | class Candy: | 3 | class Candy: | ||
4 | def __init__(self, mass, uranium): | 4 | def __init__(self, mass, uranium): | ||
5 | self.mass = mass | 5 | self.mass = mass | ||
6 | self.uranium = uranium | 6 | self.uranium = uranium | ||
7 | 7 | ||||
8 | def get_uranium_quantity(self): | 8 | def get_uranium_quantity(self): | ||
9 | return self.mass * self.uranium | 9 | return self.mass * self.uranium | ||
10 | 10 | ||||
11 | def get_mass(self): | 11 | def get_mass(self): | ||
12 | return self.mass | 12 | return self.mass | ||
13 | 13 | ||||
14 | 14 | ||||
15 | class Person: | 15 | class Person: | ||
16 | def __init__(self, position): | 16 | def __init__(self, position): | ||
17 | self.position = tuple(position) | 17 | self.position = tuple(position) | ||
18 | 18 | ||||
19 | def get_position(self): | 19 | def get_position(self): | ||
20 | return self.position | 20 | return self.position | ||
21 | 21 | ||||
22 | def set_position(self, new_pos): | 22 | def set_position(self, new_pos): | ||
23 | self.position = new_pos | 23 | self.position = new_pos | ||
24 | 24 | ||||
25 | 25 | ||||
26 | class Kid(Person): | 26 | class Kid(Person): | ||
27 | 27 | ||||
28 | max_uran = 20 | 28 | max_uran = 20 | ||
29 | 29 | ||||
30 | def __init__(self, position, initiative): | 30 | def __init__(self, position, initiative): | ||
31 | super().__init__(position) | 31 | super().__init__(position) | ||
32 | self.initiative = initiative | 32 | self.initiative = initiative | ||
33 | self.uranium_quantity = 0 | 33 | self.uranium_quantity = 0 | ||
34 | #this is a variable for later, which is useful in class FluxCapacitor | 34 | #this is a variable for later, which is useful in class FluxCapacitor | ||
35 | self.unvisited_hosts = [] | 35 | self.unvisited_hosts = [] | ||
36 | 36 | ||||
37 | def get_initiative(self): | 37 | def get_initiative(self): | ||
38 | return self.initiative | 38 | return self.initiative | ||
39 | 39 | ||||
40 | def add_candy(self, candy): | 40 | def add_candy(self, candy): | ||
41 | self.uranium_quantity += candy.get_uranium_quantity() | 41 | self.uranium_quantity += candy.get_uranium_quantity() | ||
42 | 42 | ||||
43 | def is_critical(self): | 43 | def is_critical(self): | ||
44 | if self.uranium_quantity > self.max_uran: | 44 | if self.uranium_quantity > self.max_uran: | ||
45 | return True | 45 | return True | ||
46 | return False | 46 | return False | ||
47 | 47 | ||||
48 | 48 | ||||
49 | class Host(Person): | 49 | class Host(Person): | ||
50 | 50 | ||||
51 | def __init__(self, position, candies): | 51 | def __init__(self, position, candies): | ||
52 | super().__init__(position) | 52 | super().__init__(position) | ||
53 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 53 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
54 | 54 | ||||
55 | def remove_candy(self, func): | 55 | def remove_candy(self, func): | ||
56 | if len(self.candies) == 0: | 56 | if len(self.candies) == 0: | ||
57 | return None | 57 | return None | ||
58 | else: | 58 | else: | ||
59 | chosen_candy = func(self.candies) | 59 | chosen_candy = func(self.candies) | ||
60 | self.candies.remove(chosen_candy) | 60 | self.candies.remove(chosen_candy) | ||
61 | return chosen_candy | 61 | return chosen_candy | ||
62 | 62 | ||||
63 | 63 | ||||
64 | class FluxCapacitor: | 64 | class FluxCapacitor: | ||
65 | 65 | ||||
66 | def __init__(self, participants): | 66 | def __init__(self, participants): | ||
67 | self.participants = participants | 67 | self.participants = participants | ||
68 | 68 | ||||
69 | #This is a help function to find the indices | 69 | #This is a help function to find the indices | ||
70 | #of duplicates in the distances from kid to host list | 70 | #of duplicates in the distances from kid to host list | ||
71 | def indices_dup_dist(distances): | 71 | def indices_dup_dist(distances): | ||
72 | list_duplicates = set() | 72 | list_duplicates = set() | ||
73 | unique_dict = {} | 73 | unique_dict = {} | ||
74 | for index, elem in enumerate(distances): | 74 | for index, elem in enumerate(distances): | ||
75 | if elem not in unique_dict: | 75 | if elem not in unique_dict: | ||
76 | unique_dict[elem] = index | 76 | unique_dict[elem] = index | ||
77 | else: | 77 | else: | ||
78 | list_duplicates.add(unique_dict[elem]) | 78 | list_duplicates.add(unique_dict[elem]) | ||
79 | list_duplicates.add(index) | 79 | list_duplicates.add(index) | ||
80 | return list(list_duplicates) | 80 | return list(list_duplicates) | ||
81 | 81 | ||||
82 | def get_victim(self): | 82 | def get_victim(self): | ||
83 | victims = set() | 83 | victims = set() | ||
84 | self.participants = list(self.participants) | 84 | self.participants = list(self.participants) | ||
85 | #print(self.participants) | 85 | #print(self.participants) | ||
86 | #this for loop assigns to the kid objects a list of unvisited hosts | 86 | #this for loop assigns to the kid objects a list of unvisited hosts | ||
87 | for kid in self.participants: | 87 | for kid in self.participants: | ||
88 | if isinstance(kid, Kid): | 88 | if isinstance(kid, Kid): | ||
89 | kid.unvisited_hosts = [x for x in self.participants | 89 | kid.unvisited_hosts = [x for x in self.participants | ||
90 | if isinstance(x, Host)] | 90 | if isinstance(x, Host)] | ||
91 | 91 | ||||
92 | while not victims: | 92 | while not victims: | ||
93 | #this for loop sends every kid to its respective host | 93 | #this for loop sends every kid to its respective host | ||
94 | for kid in self.participants: | 94 | for kid in self.participants: | ||
95 | if isinstance(kid, Kid): | 95 | if isinstance(kid, Kid): | ||
96 | hosts = [x for x in kid.unvisited_hosts | 96 | hosts = [x for x in kid.unvisited_hosts | ||
97 | if isinstance(x, Host)] | 97 | if isinstance(x, Host)] | ||
98 | hosts_coord = [x.position for x in hosts] | 98 | hosts_coord = [x.position for x in hosts] | ||
99 | distances = [math.sqrt((x[0] - kid.position[0]) ** 2 + | 99 | distances = [math.sqrt((x[0] - kid.position[0]) ** 2 + | ||
100 | (x[1] - kid.position[1]) ** 2) | 100 | (x[1] - kid.position[1]) ** 2) | ||
101 | for x in hosts_coord] | 101 | for x in hosts_coord] | ||
102 | closest_host = [] | 102 | closest_host = [] | ||
103 | 103 | ||||
104 | if len(distances) > len(set(distances)): | 104 | if len(distances) > len(set(distances)): | ||
105 | indices = FluxCapacitor.indices_dup_dist(distances) | 105 | indices = FluxCapacitor.indices_dup_dist(distances) | ||
106 | x_coord = [] | 106 | x_coord = [] | ||
107 | y_coord = [] | 107 | y_coord = [] | ||
108 | for index in indices: | 108 | for index in indices: | ||
109 | x_coord.append(hosts_coord[index][0]) | 109 | x_coord.append(hosts_coord[index][0]) | ||
110 | y_coord.append(hosts_coord[index][1]) | 110 | y_coord.append(hosts_coord[index][1]) | ||
111 | if len(set(x_coord)) > 1: | 111 | if len(set(x_coord)) > 1: | ||
112 | least_x_val = x_coord.index(min(x_coord)) | 112 | least_x_val = x_coord.index(min(x_coord)) | ||
113 | closest_host = hosts[least_x_val] | 113 | closest_host = hosts[least_x_val] | ||
114 | else: | 114 | else: | ||
115 | least_y_val = y_coord.index(min(y_coord)) | 115 | least_y_val = y_coord.index(min(y_coord)) | ||
116 | closest_host = hosts[least_y_val] | 116 | closest_host = hosts[least_y_val] | ||
117 | kid.set_position(closest_host.position) | 117 | kid.set_position(closest_host.position) | ||
118 | kid.unvisited_hosts.remove(closest_host) | 118 | kid.unvisited_hosts.remove(closest_host) | ||
119 | continue | 119 | continue | ||
120 | 120 | ||||
121 | closest_host = hosts[distances.index(min(distances))] | 121 | closest_host = hosts[distances.index(min(distances))] | ||
122 | kid.set_position(closest_host.position) | 122 | kid.set_position(closest_host.position) | ||
123 | kid.unvisited_hosts.remove(closest_host) | 123 | kid.unvisited_hosts.remove(closest_host) | ||
124 | 124 | ||||
125 | #this loop gives every kid candies from the hosts | 125 | #this loop gives every kid candies from the hosts | ||
126 | for host in self.participants: | 126 | for host in self.participants: | ||
127 | if isinstance(host, Host): | 127 | if isinstance(host, Host): | ||
128 | if len(host.candies) > 0: | 128 | if len(host.candies) > 0: | ||
129 | kids = [x for x in self.participants | 129 | kids = [x for x in self.participants | ||
130 | if isinstance(x, Kid)] | 130 | if isinstance(x, Kid)] | ||
131 | kids_at_host = [] | 131 | kids_at_host = [] | ||
132 | for kid in kids: | 132 | for kid in kids: | ||
133 | if kid.position == host.position: | 133 | if kid.position == host.position: | ||
134 | kids_at_host.append(kid) | 134 | kids_at_host.append(kid) | ||
135 | kid_init = [] | 135 | kid_init = [] | ||
136 | 136 | ||||
137 | for kid in kids_at_host: | 137 | for kid in kids_at_host: | ||
138 | kid_init.append(kid.initiative) | 138 | kid_init.append(kid.initiative) | ||
139 | 139 | ||||
140 | while len(kid_init) > 0 and len(host.candies) > 0: | 140 | while len(kid_init) > 0 and len(host.candies) > 0: | ||
141 | kid_index = kid_init.index(max(kid_init)) | 141 | kid_index = kid_init.index(max(kid_init)) | ||
142 | kid = kids_at_host[kid_index] | 142 | kid = kids_at_host[kid_index] | ||
143 | kid.add_candy(host.remove_candy(candy_max_mass)) | 143 | kid.add_candy(host.remove_candy(candy_max_mass)) | ||
144 | kid_init.pop(kid_index) | 144 | kid_init.pop(kid_index) | ||
145 | 145 | ||||
146 | after_loop_kids = [x for x in self.participants if | 146 | after_loop_kids = [x for x in self.participants if | ||
147 | isinstance(x, Kid)] | 147 | isinstance(x, Kid)] | ||
148 | 148 | ||||
149 | kids_ur = [x.is_critical() for x in after_loop_kids] | 149 | kids_ur = [x.is_critical() for x in after_loop_kids] | ||
150 | 150 | ||||
151 | #here we add the victims, if there are any, in a set | 151 | #here we add the victims, if there are any, in a set | ||
152 | for index, boolean_val in enumerate(kids_ur): | 152 | for index, boolean_val in enumerate(kids_ur): | ||
153 | if boolean_val == True: | 153 | if boolean_val == True: | ||
154 | victims.add(after_loop_kids[index]) | 154 | victims.add(after_loop_kids[index]) | ||
155 | 155 | ||||
156 | if len(victims) > 0: | 156 | if len(victims) > 0: | ||
157 | break | 157 | break | ||
158 | 158 | ||||
159 | for kid in after_loop_kids: | 159 | for kid in after_loop_kids: | ||
160 | if not kid.unvisited_hosts: | 160 | if not kid.unvisited_hosts: | ||
161 | return None | 161 | return None | ||
162 | continue | 162 | continue | ||
163 | 163 | ||||
164 | return victims | 164 | return victims | ||
165 | 165 | ||||
166 | 166 | ||||
167 | def candy_max_mass(treats): | 167 | def candy_max_mass(treats): | ||
168 | new_list = [x.get_mass() for x in treats] | 168 | new_list = [x.get_mass() for x in treats] | ||
169 | max_index = new_list.index(max(new_list)) | 169 | max_index = new_list.index(max(new_list)) | ||
170 | return treats[max_index] | 170 | return treats[max_index] | ||
t | 171 | t | |||
172 | |||||
173 | kid1 = Kid((0,0), 123) | ||||
174 | kid2 = Kid((-2,0), 500) | ||||
175 | host1 = Host((3, 4), [(12, 1.0), (14, 1.0)]) | ||||
176 | host2 = Host((-1, 2), [(5, 0.7), (4, 0.3)]) | ||||
177 | host3 = Host((-1, -2), [(18, 1.0), (20, 0.8)]) | ||||
178 | host4 = Host((1, -2), [(5, 1.0), (10, 1.0)]) | ||||
179 | |||||
180 | flux_cap = FluxCapacitor({kid1, kid2, host1, host2, host3, host4}) | ||||
181 | result = flux_cap.get_victim() | ||||
182 | |||||
183 | print(result) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | class Candy: | 3 | class Candy: | ||
4 | def __init__(self, mass, uranium): | 4 | def __init__(self, mass, uranium): | ||
5 | self.mass = mass | 5 | self.mass = mass | ||
6 | self.uranium = uranium | 6 | self.uranium = uranium | ||
7 | 7 | ||||
8 | def get_uranium_quantity(self): | 8 | def get_uranium_quantity(self): | ||
9 | return self.mass * self.uranium | 9 | return self.mass * self.uranium | ||
10 | 10 | ||||
11 | def get_mass(self): | 11 | def get_mass(self): | ||
12 | return self.mass | 12 | return self.mass | ||
13 | 13 | ||||
14 | 14 | ||||
15 | class Person: | 15 | class Person: | ||
16 | def __init__(self, position): | 16 | def __init__(self, position): | ||
17 | self.position = tuple(position) | 17 | self.position = tuple(position) | ||
18 | 18 | ||||
19 | def get_position(self): | 19 | def get_position(self): | ||
20 | return self.position | 20 | return self.position | ||
21 | 21 | ||||
22 | def set_position(self, new_pos): | 22 | def set_position(self, new_pos): | ||
23 | self.position = new_pos | 23 | self.position = new_pos | ||
24 | 24 | ||||
25 | 25 | ||||
26 | class Kid(Person): | 26 | class Kid(Person): | ||
27 | 27 | ||||
n | n | 28 | max_uran = 20 | ||
29 | |||||
28 | def __init__(self, position, initiative): | 30 | def __init__(self, position, initiative): | ||
29 | super().__init__(position) | 31 | super().__init__(position) | ||
30 | self.initiative = initiative | 32 | self.initiative = initiative | ||
n | 31 | self.kid_basket = [] | n | 33 | self.uranium_quantity = 0 |
32 | #this is a variable for later, which is useful in class FluxCapacitor | 34 | #this is a variable for later, which is useful in class FluxCapacitor | ||
33 | self.unvisited_hosts = [] | 35 | self.unvisited_hosts = [] | ||
n | 34 | n | 36 | ||
35 | def get_initiative(self): | 37 | def get_initiative(self): | ||
36 | return self.initiative | 38 | return self.initiative | ||
37 | 39 | ||||
38 | def add_candy(self, candy): | 40 | def add_candy(self, candy): | ||
n | 39 | self.kid_basket.append(candy.get_uranium_quantity()) | n | 41 | self.uranium_quantity += candy.get_uranium_quantity() |
40 | 42 | ||||
41 | def is_critical(self): | 43 | def is_critical(self): | ||
n | 42 | sum_uranium = 0 | n | 44 | if self.uranium_quantity > self.max_uran: |
43 | for elem in self.kid_basket: | ||||
44 | sum_uranium += elem | ||||
45 | if sum_uranium > 20: | ||||
46 | return True | 45 | return True | ||
47 | return False | 46 | return False | ||
48 | 47 | ||||
49 | 48 | ||||
50 | class Host(Person): | 49 | class Host(Person): | ||
51 | 50 | ||||
52 | def __init__(self, position, candies): | 51 | def __init__(self, position, candies): | ||
53 | super().__init__(position) | 52 | super().__init__(position) | ||
54 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 53 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
55 | 54 | ||||
56 | def remove_candy(self, func): | 55 | def remove_candy(self, func): | ||
57 | if len(self.candies) == 0: | 56 | if len(self.candies) == 0: | ||
58 | return None | 57 | return None | ||
59 | else: | 58 | else: | ||
60 | chosen_candy = func(self.candies) | 59 | chosen_candy = func(self.candies) | ||
61 | self.candies.remove(chosen_candy) | 60 | self.candies.remove(chosen_candy) | ||
62 | return chosen_candy | 61 | return chosen_candy | ||
63 | 62 | ||||
64 | 63 | ||||
65 | class FluxCapacitor: | 64 | class FluxCapacitor: | ||
66 | 65 | ||||
67 | def __init__(self, participants): | 66 | def __init__(self, participants): | ||
n | 68 | self.participants = list(participants) | n | 67 | self.participants = participants |
69 | 68 | ||||
70 | #This is a help function to find the indices | 69 | #This is a help function to find the indices | ||
71 | #of duplicates in the distances from kid to host list | 70 | #of duplicates in the distances from kid to host list | ||
72 | def indices_dup_dist(distances): | 71 | def indices_dup_dist(distances): | ||
73 | list_duplicates = set() | 72 | list_duplicates = set() | ||
74 | unique_dict = {} | 73 | unique_dict = {} | ||
75 | for index, elem in enumerate(distances): | 74 | for index, elem in enumerate(distances): | ||
76 | if elem not in unique_dict: | 75 | if elem not in unique_dict: | ||
77 | unique_dict[elem] = index | 76 | unique_dict[elem] = index | ||
78 | else: | 77 | else: | ||
79 | list_duplicates.add(unique_dict[elem]) | 78 | list_duplicates.add(unique_dict[elem]) | ||
80 | list_duplicates.add(index) | 79 | list_duplicates.add(index) | ||
81 | return list(list_duplicates) | 80 | return list(list_duplicates) | ||
82 | 81 | ||||
83 | def get_victim(self): | 82 | def get_victim(self): | ||
84 | victims = set() | 83 | victims = set() | ||
n | 85 | self.participants = set(self.participants) | n | 84 | self.participants = list(self.participants) |
86 | 85 | #print(self.participants) | |||
87 | #this for loop assigns to the kid objects a list of unvisited hosts | 86 | #this for loop assigns to the kid objects a list of unvisited hosts | ||
88 | for kid in self.participants: | 87 | for kid in self.participants: | ||
89 | if isinstance(kid, Kid): | 88 | if isinstance(kid, Kid): | ||
90 | kid.unvisited_hosts = [x for x in self.participants | 89 | kid.unvisited_hosts = [x for x in self.participants | ||
91 | if isinstance(x, Host)] | 90 | if isinstance(x, Host)] | ||
92 | 91 | ||||
93 | while not victims: | 92 | while not victims: | ||
n | 94 | '''this for loop sends every kid to its respective host''' | n | 93 | #this for loop sends every kid to its respective host |
95 | for kid in self.participants: | 94 | for kid in self.participants: | ||
96 | if isinstance(kid, Kid): | 95 | if isinstance(kid, Kid): | ||
97 | hosts = [x for x in kid.unvisited_hosts | 96 | hosts = [x for x in kid.unvisited_hosts | ||
98 | if isinstance(x, Host)] | 97 | if isinstance(x, Host)] | ||
99 | hosts_coord = [x.position for x in hosts] | 98 | hosts_coord = [x.position for x in hosts] | ||
100 | distances = [math.sqrt((x[0] - kid.position[0]) ** 2 + | 99 | distances = [math.sqrt((x[0] - kid.position[0]) ** 2 + | ||
101 | (x[1] - kid.position[1]) ** 2) | 100 | (x[1] - kid.position[1]) ** 2) | ||
102 | for x in hosts_coord] | 101 | for x in hosts_coord] | ||
103 | closest_host = [] | 102 | closest_host = [] | ||
104 | 103 | ||||
105 | if len(distances) > len(set(distances)): | 104 | if len(distances) > len(set(distances)): | ||
106 | indices = FluxCapacitor.indices_dup_dist(distances) | 105 | indices = FluxCapacitor.indices_dup_dist(distances) | ||
n | 107 | n | |||
108 | x_coord = [] | 106 | x_coord = [] | ||
109 | y_coord = [] | 107 | y_coord = [] | ||
110 | for index in indices: | 108 | for index in indices: | ||
111 | x_coord.append(hosts_coord[index][0]) | 109 | x_coord.append(hosts_coord[index][0]) | ||
112 | y_coord.append(hosts_coord[index][1]) | 110 | y_coord.append(hosts_coord[index][1]) | ||
113 | if len(set(x_coord)) > 1: | 111 | if len(set(x_coord)) > 1: | ||
114 | least_x_val = x_coord.index(min(x_coord)) | 112 | least_x_val = x_coord.index(min(x_coord)) | ||
115 | closest_host = hosts[least_x_val] | 113 | closest_host = hosts[least_x_val] | ||
116 | else: | 114 | else: | ||
117 | least_y_val = y_coord.index(min(y_coord)) | 115 | least_y_val = y_coord.index(min(y_coord)) | ||
118 | closest_host = hosts[least_y_val] | 116 | closest_host = hosts[least_y_val] | ||
119 | kid.set_position(closest_host.position) | 117 | kid.set_position(closest_host.position) | ||
120 | kid.unvisited_hosts.remove(closest_host) | 118 | kid.unvisited_hosts.remove(closest_host) | ||
121 | continue | 119 | continue | ||
122 | 120 | ||||
123 | closest_host = hosts[distances.index(min(distances))] | 121 | closest_host = hosts[distances.index(min(distances))] | ||
124 | kid.set_position(closest_host.position) | 122 | kid.set_position(closest_host.position) | ||
125 | kid.unvisited_hosts.remove(closest_host) | 123 | kid.unvisited_hosts.remove(closest_host) | ||
126 | 124 | ||||
127 | #this loop gives every kid candies from the hosts | 125 | #this loop gives every kid candies from the hosts | ||
128 | for host in self.participants: | 126 | for host in self.participants: | ||
129 | if isinstance(host, Host): | 127 | if isinstance(host, Host): | ||
130 | if len(host.candies) > 0: | 128 | if len(host.candies) > 0: | ||
131 | kids = [x for x in self.participants | 129 | kids = [x for x in self.participants | ||
132 | if isinstance(x, Kid)] | 130 | if isinstance(x, Kid)] | ||
133 | kids_at_host = [] | 131 | kids_at_host = [] | ||
134 | for kid in kids: | 132 | for kid in kids: | ||
135 | if kid.position == host.position: | 133 | if kid.position == host.position: | ||
136 | kids_at_host.append(kid) | 134 | kids_at_host.append(kid) | ||
137 | kid_init = [] | 135 | kid_init = [] | ||
n | n | 136 | |||
138 | for kid in kids_at_host: | 137 | for kid in kids_at_host: | ||
139 | kid_init.append(kid.initiative) | 138 | kid_init.append(kid.initiative) | ||
140 | 139 | ||||
141 | while len(kid_init) > 0 and len(host.candies) > 0: | 140 | while len(kid_init) > 0 and len(host.candies) > 0: | ||
142 | kid_index = kid_init.index(max(kid_init)) | 141 | kid_index = kid_init.index(max(kid_init)) | ||
143 | kid = kids_at_host[kid_index] | 142 | kid = kids_at_host[kid_index] | ||
144 | kid.add_candy(host.remove_candy(candy_max_mass)) | 143 | kid.add_candy(host.remove_candy(candy_max_mass)) | ||
n | 145 | kid_init.remove(kid.initiative) | n | 144 | kid_init.pop(kid_index) |
146 | 145 | ||||
147 | |||||
148 | after_loop_kids = [x for x in self.participants if | 146 | after_loop_kids = [x for x in self.participants if | ||
149 | isinstance(x, Kid)] | 147 | isinstance(x, Kid)] | ||
150 | 148 | ||||
151 | kids_ur = [x.is_critical() for x in after_loop_kids] | 149 | kids_ur = [x.is_critical() for x in after_loop_kids] | ||
152 | 150 | ||||
n | 153 | #here we add if there are any victims in a set | n | 151 | #here we add the victims, if there are any, in a set |
154 | for index, boolean_val in enumerate(kids_ur): | 152 | for index, boolean_val in enumerate(kids_ur): | ||
155 | if boolean_val == True: | 153 | if boolean_val == True: | ||
156 | victims.add(after_loop_kids[index]) | 154 | victims.add(after_loop_kids[index]) | ||
157 | 155 | ||||
158 | if len(victims) > 0: | 156 | if len(victims) > 0: | ||
159 | break | 157 | break | ||
160 | 158 | ||||
161 | for kid in after_loop_kids: | 159 | for kid in after_loop_kids: | ||
162 | if not kid.unvisited_hosts: | 160 | if not kid.unvisited_hosts: | ||
163 | return None | 161 | return None | ||
164 | continue | 162 | continue | ||
165 | 163 | ||||
166 | return victims | 164 | return victims | ||
167 | 165 | ||||
n | n | 166 | |||
168 | def candy_max_mass(treats): | 167 | def candy_max_mass(treats): | ||
169 | new_list = [x.get_mass() for x in treats] | 168 | new_list = [x.get_mass() for x in treats] | ||
170 | max_index = new_list.index(max(new_list)) | 169 | max_index = new_list.index(max(new_list)) | ||
171 | return treats[max_index] | 170 | return treats[max_index] | ||
t | t | 171 | |||
172 | |||||
173 | kid1 = Kid((0,0), 123) | ||||
174 | kid2 = Kid((-2,0), 500) | ||||
175 | host1 = Host((3, 4), [(12, 1.0), (14, 1.0)]) | ||||
176 | host2 = Host((-1, 2), [(5, 0.7), (4, 0.3)]) | ||||
177 | host3 = Host((-1, -2), [(18, 1.0), (20, 0.8)]) | ||||
178 | host4 = Host((1, -2), [(5, 1.0), (10, 1.0)]) | ||||
179 | |||||
180 | flux_cap = FluxCapacitor({kid1, kid2, host1, host2, host3, host4}) | ||||
181 | result = flux_cap.get_victim() | ||||
182 | |||||
183 | print(result) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|