1class Candy:
2 def __init__(self, mass, uranium):
3 self.mass = mass
4 self.uranium = uranium
5
6 def get_uranium_quantity(self):
7 return self.mass * self.uranium
8
9 def get_mass(self):
10 return self.mass
11
12
13class Person:
14 def __init__(self, position):
15 self.position = position
16
17 def get_position(self):
18 return self.position
19
20 def set_position(self, position):
21 self.position = position
22
23 def get_distance_to_other(self, other):
24 return ((self.position[0] - other.position[0]) ** 2 + (self.position[1] - other.position[1]) ** 2) ** (1/2)
25
26
27class Kid(Person):
28 MAX_URANIUM = 20
29 def __init__(self, position, initiative):
30 super().__init__(position)
31 self.initiative = initiative
32 self.uranium_sum = 0
33 self.candies = []
34 self.hosts = []
35
36 def get_initiative(self):
37 return self.initiative
38
39 def add_candy(self, candy):
40 if candy is not None:
41 self.candies.append(candy)
42 self.uranium_sum += candy.get_uranium_quantity()
43
44 def is_critical(self):
45 return self.uranium_sum > self.MAX_URANIUM
46
47 def go_to_host(self):
48 if len(self.hosts) == 0:
49 return
50
51 if len(self.hosts) == 1:
52 self.add_candy(self.hosts[0].remove_candy(Host.max_candy_mass))
53 self.hosts.pop(0)
54 return
55
56 min_dist = self.get_distance_to_other(self.hosts[0])
57 min_host = self.hosts[0]
58
59 for host in self.hosts[1:]:
60 if (curr := self.get_distance_to_other(host)) < min_dist:
61 min_host = host
62 min_dist = curr
63 elif self.get_distance_to_other(host) == min_dist:
64 if self.position[0] < min_host.position[0]:
65 min_host = host
66 elif self.position[0] == min_host.position[0]:
67 if self.position[1] < min_host.position[1]:
68 min_host = host
69
70 self.add_candy(min_host.remove_candy(Host.max_candy_mass))
71 self.position = min_host.position
72 self.hosts.remove(min_host)
73
74
75class Host(Person):
76
77 @staticmethod
78 def max_candy_mass(candies):
79 return max(candies, key=lambda c: c.mass)
80
81 def __init__(self, position, candies):
82 super().__init__(position)
83 self.candies = []
84 for (mass, uranium) in candies:
85 self.candies.append(Candy(mass, uranium))
86
87 def remove_candy(self, func):
88 if len(self.candies) == 0:
89 return None
90 candy_to_remove = func(self.candies)
91 self.candies.remove(candy_to_remove)
92 return candy_to_remove
93
94
95class FluxCapacitor:
96 def __init__(self, participants):
97 self.kids = list(filter(lambda p: type(p) is Kid, participants))
98 self.kids.sort(reverse=True, key=lambda kid: kid.initiative)
99 self.hosts = list(filter(lambda p: type(p) is Host, participants))
100 self.died = set()
101 for kid in self.kids:
102 for host in self.hosts:
103 kid.hosts.append(host)
104
105 def get_victim(self):
106 while True:
107 for kid in self.kids:
108 kid.go_to_host()
109 if kid.is_critical():
110 self.died.add(kid)
111 if len(self.died) != 0:
112 return self.died
113 are_all_empty = True
114 for kid in self.kids:
115 if len(kid.hosts) != 0:
116 are_all_empty = False
117 if are_all_empty:
118 return None
............
----------------------------------------------------------------------
Ran 12 tests in 0.001s
OK
07.11.2023 14:41
07.11.2023 14:41