1import math
2
3class Candy:
4
5 def __init__(self, mass, uranium):
6 self.mass = mass
7 self.uranium = uranium
8
9 def get_uranium_quantity(self):
10 return self.mass * self.uranium
11
12 def get_mass(self):
13 return self.mass
14
15 @staticmethod
16 def candy_with_max_mass(candy_list):
17 if candy_list:
18 return max(candy_list, key=lambda candy: candy.get_mass())
19
20
21class Person:
22
23 def __init__(self, position):
24 self.position = position
25
26 def get_position(self):
27 return self.position
28
29 def set_position(self, newPosition):
30 self.position = newPosition
31
32 @staticmethod
33 def euclidean_distance(position1, position2):
34 return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2)
35
36
37class Kid(Person):
38
39 MAX_URANIUM_QUANTITY = 20
40
41 def __init__(self, position, initiative):
42 super().__init__(position)
43 self.initiative = initiative
44 self.candy_basket = []
45
46 def get_initiative(self):
47 return self.initiative
48
49 def add_candy(self, candy):
50 self.candy_basket.append(candy)
51
52 def is_critical(self):
53 return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > self.MAX_URANIUM_QUANTITY
54
55
56class Host(Person):
57
58 def __init__(self, position, candies):
59 super().__init__(position)
60 self.candies = [Candy(mass, uranium) for mass, uranium in candies]
61
62 def remove_candy(self, func):
63 if not self.candies:
64 return None
65 else:
66 selected_candy = func(self.candies)
67 self.candies.remove(selected_candy)
68 return selected_candy
69
70
71class FluxCapacitor:
72
73 def __init__(self, participants):
74 self.participants = participants
75 self.kids = [kid for kid in self.participants if isinstance(kid, Kid)]
76 self.hosts = [host for host in self.participants if isinstance(host, Host)]
77
78 def get_victim(self):
79 counter = 0
80
81 self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True)
82
83 visited_host = {kid: [] for kid in self.kids}
84 kids_coming_to_host = {host: [] for host in self.hosts}
85
86 while True:
87 if counter // len(self.hosts) >= len(self.kids):
88 return None
89 for kid in self.kids:
90 min_distance = float('inf')
91 closest_host = None
92
93 for host in self.hosts:
94 if host in visited_host:
95 continue
96
97 distance = Person.euclidean_distance(host.get_position(), kid.get_position())
98
99 if distance < min_distance:
100 min_distance = distance
101 closest_host = host
102 elif distance == min_distance:
103 if closest_host.get_position()[0] > host.get_position()[0]:
104 closest_host = host
105 elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]:
106 closest_host = host
107
108 visited_host[kid].append(closest_host)
109 kids_coming_to_host[closest_host].append(kid)
110
111 for host in self.hosts:
112 for kid in kids_coming_to_host[host]:
113 counter += 1
114 if not host.candies:
115 break
116 kid.add_candy(host.remove_candy(Candy.candy_with_max_mass))
117 kid.set_position(host.get_position())
118
119 critical_victims = {kid for kid in self.kids if kid.is_critical()}
120
121 if critical_victims:
122 return critical_victims
123
.EE.........
======================================================================
ERROR: 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 87, in get_victim
if counter // len(self.hosts) >= len(self.kids):
ZeroDivisionError: integer division or modulo by zero
======================================================================
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 87, in get_victim
if counter // len(self.hosts) >= len(self.kids):
ZeroDivisionError: integer division or modulo by zero
----------------------------------------------------------------------
Ran 12 tests in 0.001s
FAILED (errors=2)
Георги Кунчев
07.11.2023 09:40Сега е ок
|
Георги Кунчев
04.11.2023 17:48Имаш безкраен цикъл и тестовете ни ще зависнат, т.е. няма да имаш точки. Моля изтествай с реален случай.
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | class Candy: | 3 | class Candy: | ||
4 | 4 | ||||
5 | def __init__(self, mass, uranium): | 5 | def __init__(self, mass, uranium): | ||
6 | self.mass = mass | 6 | self.mass = mass | ||
7 | self.uranium = uranium | 7 | self.uranium = uranium | ||
8 | 8 | ||||
9 | def get_uranium_quantity(self): | 9 | def get_uranium_quantity(self): | ||
10 | return self.mass * self.uranium | 10 | return self.mass * self.uranium | ||
11 | 11 | ||||
12 | def get_mass(self): | 12 | def get_mass(self): | ||
13 | return self.mass | 13 | return self.mass | ||
14 | 14 | ||||
15 | @staticmethod | 15 | @staticmethod | ||
16 | def candy_with_max_mass(candy_list): | 16 | def candy_with_max_mass(candy_list): | ||
17 | if candy_list: | 17 | if candy_list: | ||
18 | return max(candy_list, key=lambda candy: candy.get_mass()) | 18 | return max(candy_list, key=lambda candy: candy.get_mass()) | ||
19 | 19 | ||||
20 | 20 | ||||
21 | class Person: | 21 | class Person: | ||
22 | 22 | ||||
23 | def __init__(self, position): | 23 | def __init__(self, position): | ||
24 | self.position = position | 24 | self.position = position | ||
25 | 25 | ||||
26 | def get_position(self): | 26 | def get_position(self): | ||
27 | return self.position | 27 | return self.position | ||
28 | 28 | ||||
29 | def set_position(self, newPosition): | 29 | def set_position(self, newPosition): | ||
30 | self.position = newPosition | 30 | self.position = newPosition | ||
31 | 31 | ||||
32 | @staticmethod | 32 | @staticmethod | ||
33 | def euclidean_distance(position1, position2): | 33 | def euclidean_distance(position1, position2): | ||
34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | 34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | ||
35 | 35 | ||||
36 | 36 | ||||
37 | class Kid(Person): | 37 | class Kid(Person): | ||
38 | 38 | ||||
39 | MAX_URANIUM_QUANTITY = 20 | 39 | MAX_URANIUM_QUANTITY = 20 | ||
40 | 40 | ||||
41 | def __init__(self, position, initiative): | 41 | def __init__(self, position, initiative): | ||
42 | super().__init__(position) | 42 | super().__init__(position) | ||
43 | self.initiative = initiative | 43 | self.initiative = initiative | ||
44 | self.candy_basket = [] | 44 | self.candy_basket = [] | ||
45 | 45 | ||||
46 | def get_initiative(self): | 46 | def get_initiative(self): | ||
47 | return self.initiative | 47 | return self.initiative | ||
48 | 48 | ||||
49 | def add_candy(self, candy): | 49 | def add_candy(self, candy): | ||
50 | self.candy_basket.append(candy) | 50 | self.candy_basket.append(candy) | ||
51 | 51 | ||||
52 | def is_critical(self): | 52 | def is_critical(self): | ||
53 | return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > self.MAX_URANIUM_QUANTITY | 53 | return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > self.MAX_URANIUM_QUANTITY | ||
54 | 54 | ||||
55 | 55 | ||||
56 | class Host(Person): | 56 | class Host(Person): | ||
57 | 57 | ||||
58 | def __init__(self, position, candies): | 58 | def __init__(self, position, candies): | ||
59 | super().__init__(position) | 59 | super().__init__(position) | ||
60 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 60 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
61 | 61 | ||||
62 | def remove_candy(self, func): | 62 | def remove_candy(self, func): | ||
63 | if not self.candies: | 63 | if not self.candies: | ||
64 | return None | 64 | return None | ||
65 | else: | 65 | else: | ||
66 | selected_candy = func(self.candies) | 66 | selected_candy = func(self.candies) | ||
67 | self.candies.remove(selected_candy) | 67 | self.candies.remove(selected_candy) | ||
68 | return selected_candy | 68 | return selected_candy | ||
69 | 69 | ||||
70 | 70 | ||||
71 | class FluxCapacitor: | 71 | class FluxCapacitor: | ||
72 | 72 | ||||
73 | def __init__(self, participants): | 73 | def __init__(self, participants): | ||
74 | self.participants = participants | 74 | self.participants = participants | ||
75 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | 75 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | ||
76 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | 76 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | ||
77 | 77 | ||||
78 | def get_victim(self): | 78 | def get_victim(self): | ||
n | n | 79 | counter = 0 | ||
80 | |||||
79 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | 81 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | ||
80 | 82 | ||||
81 | visited_host = {kid: [] for kid in self.kids} | 83 | visited_host = {kid: [] for kid in self.kids} | ||
82 | kids_coming_to_host = {host: [] for host in self.hosts} | 84 | kids_coming_to_host = {host: [] for host in self.hosts} | ||
83 | 85 | ||||
84 | while True: | 86 | while True: | ||
n | 85 | if all(len(kids_coming_to_host[host]) >= len(self.kids) for host in kids_coming_to_host): | n | 87 | if counter // len(self.hosts) >= len(self.kids): |
86 | return None | 88 | return None | ||
87 | |||||
88 | for kid in self.kids: | 89 | for kid in self.kids: | ||
89 | min_distance = float('inf') | 90 | min_distance = float('inf') | ||
90 | closest_host = None | 91 | closest_host = None | ||
91 | 92 | ||||
92 | for host in self.hosts: | 93 | for host in self.hosts: | ||
93 | if host in visited_host: | 94 | if host in visited_host: | ||
94 | continue | 95 | continue | ||
95 | 96 | ||||
96 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) | 97 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) | ||
97 | 98 | ||||
98 | if distance < min_distance: | 99 | if distance < min_distance: | ||
99 | min_distance = distance | 100 | min_distance = distance | ||
100 | closest_host = host | 101 | closest_host = host | ||
101 | elif distance == min_distance: | 102 | elif distance == min_distance: | ||
102 | if closest_host.get_position()[0] > host.get_position()[0]: | 103 | if closest_host.get_position()[0] > host.get_position()[0]: | ||
103 | closest_host = host | 104 | closest_host = host | ||
104 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | 105 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | ||
105 | closest_host = host | 106 | closest_host = host | ||
106 | 107 | ||||
107 | visited_host[kid].append(closest_host) | 108 | visited_host[kid].append(closest_host) | ||
108 | kids_coming_to_host[closest_host].append(kid) | 109 | kids_coming_to_host[closest_host].append(kid) | ||
109 | 110 | ||||
110 | for host in self.hosts: | 111 | for host in self.hosts: | ||
111 | for kid in kids_coming_to_host[host]: | 112 | for kid in kids_coming_to_host[host]: | ||
t | t | 113 | counter += 1 | ||
112 | if not host.candies: | 114 | if not host.candies: | ||
113 | break | 115 | break | ||
114 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | 116 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | ||
115 | kid.set_position(host.get_position()) | 117 | kid.set_position(host.get_position()) | ||
116 | 118 | ||||
117 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | 119 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | ||
118 | 120 | ||||
119 | if critical_victims: | 121 | if critical_victims: | ||
120 | return critical_victims | 122 | return critical_victims | ||
121 | 123 |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | class Candy: | 3 | class Candy: | ||
4 | 4 | ||||
n | 5 | def __init__(self, mass, uranium) -> None: | n | 5 | def __init__(self, mass, uranium): |
6 | self.mass = mass | 6 | self.mass = mass | ||
7 | self.uranium = uranium | 7 | self.uranium = uranium | ||
8 | 8 | ||||
9 | def get_uranium_quantity(self): | 9 | def get_uranium_quantity(self): | ||
10 | return self.mass * self.uranium | 10 | return self.mass * self.uranium | ||
11 | 11 | ||||
12 | def get_mass(self): | 12 | def get_mass(self): | ||
13 | return self.mass | 13 | return self.mass | ||
14 | 14 | ||||
15 | @staticmethod | 15 | @staticmethod | ||
16 | def candy_with_max_mass(candy_list): | 16 | def candy_with_max_mass(candy_list): | ||
17 | if candy_list: | 17 | if candy_list: | ||
18 | return max(candy_list, key=lambda candy: candy.get_mass()) | 18 | return max(candy_list, key=lambda candy: candy.get_mass()) | ||
19 | 19 | ||||
20 | 20 | ||||
21 | class Person: | 21 | class Person: | ||
22 | 22 | ||||
n | 23 | def __init__(self, position) -> None: | n | 23 | def __init__(self, position): |
24 | self.position = position | 24 | self.position = position | ||
25 | 25 | ||||
26 | def get_position(self): | 26 | def get_position(self): | ||
27 | return self.position | 27 | return self.position | ||
28 | 28 | ||||
29 | def set_position(self, newPosition): | 29 | def set_position(self, newPosition): | ||
30 | self.position = newPosition | 30 | self.position = newPosition | ||
31 | 31 | ||||
32 | @staticmethod | 32 | @staticmethod | ||
33 | def euclidean_distance(position1, position2): | 33 | def euclidean_distance(position1, position2): | ||
34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | 34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | ||
35 | 35 | ||||
36 | 36 | ||||
37 | class Kid(Person): | 37 | class Kid(Person): | ||
38 | 38 | ||||
n | n | 39 | MAX_URANIUM_QUANTITY = 20 | ||
40 | |||||
39 | def __init__(self, position, initiative) -> None: | 41 | def __init__(self, position, initiative): | ||
40 | super().__init__(position) | 42 | super().__init__(position) | ||
41 | self.initiative = initiative | 43 | self.initiative = initiative | ||
42 | self.candy_basket = [] | 44 | self.candy_basket = [] | ||
43 | 45 | ||||
44 | def get_initiative(self): | 46 | def get_initiative(self): | ||
45 | return self.initiative | 47 | return self.initiative | ||
46 | 48 | ||||
47 | def add_candy(self, candy): | 49 | def add_candy(self, candy): | ||
48 | self.candy_basket.append(candy) | 50 | self.candy_basket.append(candy) | ||
49 | 51 | ||||
50 | def is_critical(self): | 52 | def is_critical(self): | ||
n | 51 | total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket) | n | 53 | return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > self.MAX_URANIUM_QUANTITY |
52 | return total_uranium > 20 | ||||
53 | 54 | ||||
54 | 55 | ||||
55 | class Host(Person): | 56 | class Host(Person): | ||
56 | 57 | ||||
n | 57 | def __init__(self, position, candies) -> None: | n | 58 | def __init__(self, position, candies): |
58 | super().__init__(position) | 59 | super().__init__(position) | ||
59 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 60 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
60 | 61 | ||||
61 | def remove_candy(self, func): | 62 | def remove_candy(self, func): | ||
62 | if not self.candies: | 63 | if not self.candies: | ||
63 | return None | 64 | return None | ||
64 | else: | 65 | else: | ||
65 | selected_candy = func(self.candies) | 66 | selected_candy = func(self.candies) | ||
66 | self.candies.remove(selected_candy) | 67 | self.candies.remove(selected_candy) | ||
67 | return selected_candy | 68 | return selected_candy | ||
68 | 69 | ||||
69 | 70 | ||||
70 | class FluxCapacitor: | 71 | class FluxCapacitor: | ||
71 | 72 | ||||
n | 72 | def __init__(self, participants) -> None: | n | 73 | def __init__(self, participants): |
73 | self.participants = participants | 74 | self.participants = participants | ||
74 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | 75 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | ||
75 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | 76 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | ||
76 | 77 | ||||
77 | def get_victim(self): | 78 | def get_victim(self): | ||
n | 78 | counter = 0 | n | ||
79 | |||||
80 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | 79 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | ||
81 | 80 | ||||
82 | visited_host = {kid: [] for kid in self.kids} | 81 | visited_host = {kid: [] for kid in self.kids} | ||
83 | kids_coming_to_host = {host: [] for host in self.hosts} | 82 | kids_coming_to_host = {host: [] for host in self.hosts} | ||
84 | 83 | ||||
85 | while True: | 84 | while True: | ||
n | 86 | if counter // len(self.hosts) >= len(self.kids): | n | 85 | if all(len(kids_coming_to_host[host]) >= len(self.kids) for host in kids_coming_to_host): |
87 | return None | 86 | return None | ||
88 | 87 | ||||
89 | for kid in self.kids: | 88 | for kid in self.kids: | ||
90 | min_distance = float('inf') | 89 | min_distance = float('inf') | ||
91 | closest_host = None | 90 | closest_host = None | ||
92 | 91 | ||||
93 | for host in self.hosts: | 92 | for host in self.hosts: | ||
94 | if host in visited_host: | 93 | if host in visited_host: | ||
95 | continue | 94 | continue | ||
96 | 95 | ||||
97 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) | 96 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) | ||
98 | 97 | ||||
99 | if distance < min_distance: | 98 | if distance < min_distance: | ||
100 | min_distance = distance | 99 | min_distance = distance | ||
101 | closest_host = host | 100 | closest_host = host | ||
102 | elif distance == min_distance: | 101 | elif distance == min_distance: | ||
103 | if closest_host.get_position()[0] > host.get_position()[0]: | 102 | if closest_host.get_position()[0] > host.get_position()[0]: | ||
104 | closest_host = host | 103 | closest_host = host | ||
105 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | 104 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | ||
106 | closest_host = host | 105 | closest_host = host | ||
107 | 106 | ||||
108 | visited_host[kid].append(closest_host) | 107 | visited_host[kid].append(closest_host) | ||
109 | kids_coming_to_host[closest_host].append(kid) | 108 | kids_coming_to_host[closest_host].append(kid) | ||
110 | 109 | ||||
111 | for host in self.hosts: | 110 | for host in self.hosts: | ||
112 | for kid in kids_coming_to_host[host]: | 111 | for kid in kids_coming_to_host[host]: | ||
t | 113 | counter += 1 | t | ||
114 | if not host.candies: | 112 | if not host.candies: | ||
115 | break | 113 | break | ||
116 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | 114 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | ||
117 | kid.set_position(host.get_position()) | 115 | kid.set_position(host.get_position()) | ||
118 | 116 | ||||
119 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | 117 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | ||
120 | 118 | ||||
121 | if critical_victims: | 119 | if critical_victims: | ||
122 | return critical_victims | 120 | return critical_victims | ||
123 | 121 |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | class Candy: | 3 | class Candy: | ||
4 | 4 | ||||
5 | def __init__(self, mass, uranium) -> None: | 5 | def __init__(self, mass, uranium) -> None: | ||
6 | self.mass = mass | 6 | self.mass = mass | ||
7 | self.uranium = uranium | 7 | self.uranium = uranium | ||
8 | 8 | ||||
9 | def get_uranium_quantity(self): | 9 | def get_uranium_quantity(self): | ||
10 | return self.mass * self.uranium | 10 | return self.mass * self.uranium | ||
11 | 11 | ||||
12 | def get_mass(self): | 12 | def get_mass(self): | ||
13 | return self.mass | 13 | return self.mass | ||
14 | 14 | ||||
15 | @staticmethod | 15 | @staticmethod | ||
16 | def candy_with_max_mass(candy_list): | 16 | def candy_with_max_mass(candy_list): | ||
17 | if candy_list: | 17 | if candy_list: | ||
18 | return max(candy_list, key=lambda candy: candy.get_mass()) | 18 | return max(candy_list, key=lambda candy: candy.get_mass()) | ||
19 | 19 | ||||
20 | 20 | ||||
21 | class Person: | 21 | class Person: | ||
22 | 22 | ||||
23 | def __init__(self, position) -> None: | 23 | def __init__(self, position) -> None: | ||
24 | self.position = position | 24 | self.position = position | ||
25 | 25 | ||||
26 | def get_position(self): | 26 | def get_position(self): | ||
27 | return self.position | 27 | return self.position | ||
28 | 28 | ||||
29 | def set_position(self, newPosition): | 29 | def set_position(self, newPosition): | ||
30 | self.position = newPosition | 30 | self.position = newPosition | ||
31 | 31 | ||||
32 | @staticmethod | 32 | @staticmethod | ||
33 | def euclidean_distance(position1, position2): | 33 | def euclidean_distance(position1, position2): | ||
34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | 34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | ||
35 | 35 | ||||
36 | 36 | ||||
37 | class Kid(Person): | 37 | class Kid(Person): | ||
38 | 38 | ||||
39 | def __init__(self, position, initiative) -> None: | 39 | def __init__(self, position, initiative) -> None: | ||
40 | super().__init__(position) | 40 | super().__init__(position) | ||
41 | self.initiative = initiative | 41 | self.initiative = initiative | ||
42 | self.candy_basket = [] | 42 | self.candy_basket = [] | ||
43 | 43 | ||||
44 | def get_initiative(self): | 44 | def get_initiative(self): | ||
45 | return self.initiative | 45 | return self.initiative | ||
46 | 46 | ||||
47 | def add_candy(self, candy): | 47 | def add_candy(self, candy): | ||
48 | self.candy_basket.append(candy) | 48 | self.candy_basket.append(candy) | ||
49 | 49 | ||||
50 | def is_critical(self): | 50 | def is_critical(self): | ||
51 | total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket) | 51 | total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket) | ||
52 | return total_uranium > 20 | 52 | return total_uranium > 20 | ||
53 | 53 | ||||
54 | 54 | ||||
55 | class Host(Person): | 55 | class Host(Person): | ||
56 | 56 | ||||
57 | def __init__(self, position, candies) -> None: | 57 | def __init__(self, position, candies) -> None: | ||
58 | super().__init__(position) | 58 | super().__init__(position) | ||
59 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 59 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
60 | 60 | ||||
61 | def remove_candy(self, func): | 61 | def remove_candy(self, func): | ||
62 | if not self.candies: | 62 | if not self.candies: | ||
63 | return None | 63 | return None | ||
64 | else: | 64 | else: | ||
65 | selected_candy = func(self.candies) | 65 | selected_candy = func(self.candies) | ||
66 | self.candies.remove(selected_candy) | 66 | self.candies.remove(selected_candy) | ||
67 | return selected_candy | 67 | return selected_candy | ||
68 | 68 | ||||
69 | 69 | ||||
70 | class FluxCapacitor: | 70 | class FluxCapacitor: | ||
71 | 71 | ||||
72 | def __init__(self, participants) -> None: | 72 | def __init__(self, participants) -> None: | ||
73 | self.participants = participants | 73 | self.participants = participants | ||
74 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | 74 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | ||
75 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | 75 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | ||
76 | 76 | ||||
77 | def get_victim(self): | 77 | def get_victim(self): | ||
78 | counter = 0 | 78 | counter = 0 | ||
79 | 79 | ||||
80 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | 80 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | ||
81 | 81 | ||||
82 | visited_host = {kid: [] for kid in self.kids} | 82 | visited_host = {kid: [] for kid in self.kids} | ||
83 | kids_coming_to_host = {host: [] for host in self.hosts} | 83 | kids_coming_to_host = {host: [] for host in self.hosts} | ||
84 | 84 | ||||
85 | while True: | 85 | while True: | ||
n | 86 | if counter // len(self.hosts) == len(self.kids): | n | 86 | if counter // len(self.hosts) >= len(self.kids): |
87 | return None | 87 | return None | ||
88 | 88 | ||||
89 | for kid in self.kids: | 89 | for kid in self.kids: | ||
90 | min_distance = float('inf') | 90 | min_distance = float('inf') | ||
91 | closest_host = None | 91 | closest_host = None | ||
n | 92 | n | 92 | ||
93 | for host in self.hosts: | 93 | for host in self.hosts: | ||
94 | if host in visited_host: | 94 | if host in visited_host: | ||
95 | continue | 95 | continue | ||
96 | 96 | ||||
97 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) | 97 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) | ||
98 | 98 | ||||
99 | if distance < min_distance: | 99 | if distance < min_distance: | ||
100 | min_distance = distance | 100 | min_distance = distance | ||
101 | closest_host = host | 101 | closest_host = host | ||
102 | elif distance == min_distance: | 102 | elif distance == min_distance: | ||
103 | if closest_host.get_position()[0] > host.get_position()[0]: | 103 | if closest_host.get_position()[0] > host.get_position()[0]: | ||
104 | closest_host = host | 104 | closest_host = host | ||
105 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | 105 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | ||
106 | closest_host = host | 106 | closest_host = host | ||
107 | 107 | ||||
108 | visited_host[kid].append(closest_host) | 108 | visited_host[kid].append(closest_host) | ||
109 | kids_coming_to_host[closest_host].append(kid) | 109 | kids_coming_to_host[closest_host].append(kid) | ||
110 | 110 | ||||
111 | for host in self.hosts: | 111 | for host in self.hosts: | ||
112 | for kid in kids_coming_to_host[host]: | 112 | for kid in kids_coming_to_host[host]: | ||
113 | counter += 1 | 113 | counter += 1 | ||
n | n | 114 | if not host.candies: | ||
115 | break | ||||
114 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | 116 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | ||
115 | kid.set_position(host.get_position()) | 117 | kid.set_position(host.get_position()) | ||
116 | 118 | ||||
117 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | 119 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | ||
118 | 120 | ||||
119 | if critical_victims: | 121 | if critical_victims: | ||
120 | return critical_victims | 122 | return critical_victims | ||
t | t | 123 |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import math | f | 1 | import math |
2 | 2 | ||||
3 | class Candy: | 3 | class Candy: | ||
4 | 4 | ||||
5 | def __init__(self, mass, uranium) -> None: | 5 | def __init__(self, mass, uranium) -> None: | ||
6 | self.mass = mass | 6 | self.mass = mass | ||
7 | self.uranium = uranium | 7 | self.uranium = uranium | ||
8 | 8 | ||||
9 | def get_uranium_quantity(self): | 9 | def get_uranium_quantity(self): | ||
10 | return self.mass * self.uranium | 10 | return self.mass * self.uranium | ||
11 | 11 | ||||
12 | def get_mass(self): | 12 | def get_mass(self): | ||
13 | return self.mass | 13 | return self.mass | ||
n | n | 14 | |||
15 | @staticmethod | ||||
16 | def candy_with_max_mass(candy_list): | ||||
17 | if candy_list: | ||||
18 | return max(candy_list, key=lambda candy: candy.get_mass()) | ||||
14 | 19 | ||||
15 | 20 | ||||
16 | class Person: | 21 | class Person: | ||
17 | 22 | ||||
18 | def __init__(self, position) -> None: | 23 | def __init__(self, position) -> None: | ||
19 | self.position = position | 24 | self.position = position | ||
20 | 25 | ||||
21 | def get_position(self): | 26 | def get_position(self): | ||
22 | return self.position | 27 | return self.position | ||
23 | 28 | ||||
24 | def set_position(self, newPosition): | 29 | def set_position(self, newPosition): | ||
25 | self.position = newPosition | 30 | self.position = newPosition | ||
n | n | 31 | |||
32 | @staticmethod | ||||
33 | def euclidean_distance(position1, position2): | ||||
34 | return math.sqrt((position2[0] - position1[0])**2 + (position2[1] - position1[1])**2) | ||||
26 | 35 | ||||
27 | 36 | ||||
28 | class Kid(Person): | 37 | class Kid(Person): | ||
29 | 38 | ||||
30 | def __init__(self, position, initiative) -> None: | 39 | def __init__(self, position, initiative) -> None: | ||
31 | super().__init__(position) | 40 | super().__init__(position) | ||
32 | self.initiative = initiative | 41 | self.initiative = initiative | ||
33 | self.candy_basket = [] | 42 | self.candy_basket = [] | ||
34 | 43 | ||||
35 | def get_initiative(self): | 44 | def get_initiative(self): | ||
36 | return self.initiative | 45 | return self.initiative | ||
37 | 46 | ||||
38 | def add_candy(self, candy): | 47 | def add_candy(self, candy): | ||
39 | self.candy_basket.append(candy) | 48 | self.candy_basket.append(candy) | ||
40 | 49 | ||||
41 | def is_critical(self): | 50 | def is_critical(self): | ||
42 | total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket) | 51 | total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket) | ||
43 | return total_uranium > 20 | 52 | return total_uranium > 20 | ||
44 | 53 | ||||
45 | 54 | ||||
46 | class Host(Person): | 55 | class Host(Person): | ||
47 | 56 | ||||
48 | def __init__(self, position, candies) -> None: | 57 | def __init__(self, position, candies) -> None: | ||
49 | super().__init__(position) | 58 | super().__init__(position) | ||
50 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 59 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
51 | 60 | ||||
52 | def remove_candy(self, func): | 61 | def remove_candy(self, func): | ||
53 | if not self.candies: | 62 | if not self.candies: | ||
54 | return None | 63 | return None | ||
55 | else: | 64 | else: | ||
56 | selected_candy = func(self.candies) | 65 | selected_candy = func(self.candies) | ||
57 | self.candies.remove(selected_candy) | 66 | self.candies.remove(selected_candy) | ||
58 | return selected_candy | 67 | return selected_candy | ||
59 | 68 | ||||
n | 60 | # Бъгна ме мега бруталното този клас 😒 | n | 69 | |
61 | class FluxCapacitor: | 70 | class FluxCapacitor: | ||
62 | 71 | ||||
63 | def __init__(self, participants) -> None: | 72 | def __init__(self, participants) -> None: | ||
64 | self.participants = participants | 73 | self.participants = participants | ||
n | n | 74 | self.kids = [kid for kid in self.participants if isinstance(kid, Kid)] | ||
75 | self.hosts = [host for host in self.participants if isinstance(host, Host)] | ||||
65 | 76 | ||||
66 | def get_victim(self): | 77 | def get_victim(self): | ||
n | 67 | all_kids = [kid for kid in self.participants if isinstance(kid, Kid)] | n | 78 | counter = 0 |
68 | all_hosts = [host for host in self.participants if isinstance(host, Host)] | 79 | |||
80 | self.kids.sort(key=lambda kid: (kid.get_initiative()), reverse=True) | ||||
81 | |||||
82 | visited_host = {kid: [] for kid in self.kids} | ||||
83 | kids_coming_to_host = {host: [] for host in self.hosts} | ||||
69 | 84 | ||||
n | 70 | all_kids.sort(key=lambda kid: (kid.get_initiative(), kid.get_position()[0], kid.get_position()[1])) | n | 85 | while True: |
71 | all_hosts.sort(key=lambda host: (host.get_position()[0], host.get_position()[1])) | 86 | if counter // len(self.hosts) == len(self.kids): | ||
72 | 87 | return None | |||
73 | visited_kids = [] | 88 | |||
74 | visited_hosts = set() | 89 | for kid in self.kids: | ||
75 | |||||
76 | while all_hosts or all_kids: | ||||
77 | for host in all_hosts: | ||||
78 | if host in visited_hosts: | ||||
79 | continue | ||||
80 | |||||
81 | min_distance = float('inf') | 90 | min_distance = float('inf') | ||
n | 82 | closest_kid = None | n | 91 | closest_host = None |
83 | 92 | ||||
84 | for kid in all_kids: | 93 | for host in self.hosts: | ||
85 | if kid in visited_hosts: | 94 | if host in visited_host: | ||
86 | continue | 95 | continue | ||
87 | 96 | ||||
n | 88 | distance = euclidean_distance(kid.get_position()[0], kid.get_position()[1], host.get_position()[0], host.get_position()[1]) | n | 97 | distance = Person.euclidean_distance(host.get_position(), kid.get_position()) |
89 | 98 | ||||
90 | if distance < min_distance: | 99 | if distance < min_distance: | ||
91 | min_distance = distance | 100 | min_distance = distance | ||
n | 92 | n | |||
93 | closest_kid = kid | 101 | closest_host = host | ||
94 | if closest_kid and host.candies: | 102 | elif distance == min_distance: | ||
95 | candy = candy_with_max_mass(host.candies) | 103 | if closest_host.get_position()[0] > host.get_position()[0]: | ||
96 | closest_kid.add_candy(candy) | 104 | closest_host = host | ||
97 | visited_kids.append(closest_kid) | 105 | elif closest_host.get_position()[0] == host.get_position()[0] and closest_host.get_position()[1] > host.get_position()[1]: | ||
98 | visited_hosts.add(host) | 106 | closest_host = host | ||
99 | all_hosts.remove(host) | ||||
100 | all_kids.remove(closest_kid) | ||||
101 | else: | ||||
102 | continue | ||||
103 | |||||
104 | critical_victims = {kid for kid in visited_kids if kid.is_critical()} | ||||
105 | 107 | ||||
n | 106 | if critical_victims: | n | 108 | visited_host[kid].append(closest_host) |
107 | return critical_victims | 109 | kids_coming_to_host[closest_host].append(kid) | ||
108 | return None | ||||
109 | |||||
110 | 110 | ||||
n | 111 | def candy_with_max_mass(candy_list): | n | 111 | for host in self.hosts: |
112 | if candy_list: | 112 | for kid in kids_coming_to_host[host]: | ||
113 | return max(candy_list, key=lambda candy: candy.get_mass()) | 113 | counter += 1 | ||
114 | return None | 114 | kid.add_candy(host.remove_candy(Candy.candy_with_max_mass)) | ||
115 | kid.set_position(host.get_position()) | ||||
115 | 116 | ||||
n | n | 117 | critical_victims = {kid for kid in self.kids if kid.is_critical()} | ||
116 | 118 | ||||
t | 117 | def euclidean_distance(x1, y1, x2, y2): | t | 119 | if critical_victims: |
118 | return math.sqrt((x2 - x1)**2 + (y2 - y1)**2) | 120 | return critical_victims |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
07.11.2023 09:41
07.11.2023 09:42