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, new_position):
21 self.position = new_position
22
23 def get_dist(self, other):
24 '''Return the distance to the other person.'''
25 return ((self.position[0] - other.position[0]) ** 2 + (self.position[1] - other.position[1]) ** 2) ** 0.5
26
27
28class Kid(Person):
29 def __init__(self, position, initiative):
30 self.position = position
31 self.initiative = initiative
32
33 def get_initiative(self):
34 return self.initiative
35
36 def add_candy(self, candy):
37 if candy is None:
38 return
39 try:
40 self.candies.append(candy)
41 except AttributeError:
42 self.candies = [candy]
43
44 def is_critical(self):
45 return sum(candy.get_uranium_quantity() for candy in self.candies) > 20
46
47
48class Host(Person):
49 def __init__(self, position, candies):
50 self.position = position
51 self.candies = [Candy(mass, uranium) for mass, uranium in candies]
52
53 def remove_candy(self, func):
54 try:
55 candy = func(self.candies)
56 self.candies.remove(candy)
57 except (AttributeError, ValueError):
58 return None
59 return candy
60
61
62class FluxCapacitor():
63 def __init__(self, participants):
64 self.kids = [member for member in participants if isinstance(member, Kid)]
65 self.hosts = [member for member in participants if isinstance(member, Host)]
66
67 @staticmethod
68 def find_closest_unvisited_host(kid, hosts, visited):
69 closest_host = -1
70 for host in hosts:
71 if host not in visited[kid]:
72 closest_host = (host, kid.get_dist(host))
73 break
74 if closest_host == -1:
75 return None
76
77 for host in hosts:
78 if host not in visited[kid] and kid.get_dist(host) < closest_host[1]:
79 closest_host = (host, kid.get_dist(host))
80 continue
81
82 if host not in visited[kid] and abs(kid.get_dist(host) - closest_host[1]) < 0.000000001:
83 if host.position[0] < closest_host[0].position[0]:
84 closest_host = (host, kid.get_dist(host))
85 continue
86 elif host.position[0] - closest_host[0].position[0] > 0.000000001:
87 continue
88 if host.position[1] < closest_host[0].position[1]:
89 closest_host = (host, kid.get_dist(host))
90
91 return closest_host
92
93
94 def get_victim(self):
95 if len(self.kids) <= 0 or len(self.hosts) <= 0:
96 return None
97
98 visited = {kid:[] for kid in self.kids}
99
100 while True:
101 host_kids = {host:[] for host in self.hosts}
102 end_game = True
103
104 for kid in self.kids:
105 closest_host = FluxCapacitor.find_closest_unvisited_host(kid, self.hosts, visited)
106 if not closest_host:
107 continue
108 end_game = False
109 host_kids[closest_host[0]].append(kid)
110 visited[kid].append(closest_host[0])
111 kid.position = closest_host[0].position
112
113 if end_game:
114 return None
115
116 for host in self.hosts:
117 while len(host_kids[host]) > 0:
118 most_initiative = max(host_kids[host], key= lambda kid: kid.initiative)
119 host_kids[host].remove(most_initiative)
120 most_heavy = host.remove_candy(lambda candies: max(candies, key= lambda candy: candy.mass))
121 most_initiative.add_candy(most_heavy)
122
123 dead_kids = {kid for kid in self.kids if kid.is_critical()}
124 if len(dead_kids) > 0:
125 return dead_kids
126
....E....E..
======================================================================
ERROR: test_no_candies (test.FluxCapacitorTest)
Test with no candies.
----------------------------------------------------------------------
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 106, in test_no_candies
self.assertEqual(flux_capacitor.get_victim(), None)
File "/tmp/solution.py", line 123, in get_victim
dead_kids = {kid for kid in self.kids if kid.is_critical()}
File "/tmp/solution.py", line 123, in <setcomp>
dead_kids = {kid for kid in self.kids if kid.is_critical()}
File "/tmp/solution.py", line 45, in is_critical
return sum(candy.get_uranium_quantity() for candy in self.candies) > 20
AttributeError: 'Kid' object has no attribute 'candies'
======================================================================
ERROR: test_candies (test.KidTest)
Test basic usage of candies in the Kid class.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 45, in test_candies
self.assertFalse(kid.is_critical())
File "/tmp/solution.py", line 45, in is_critical
return sum(candy.get_uranium_quantity() for candy in self.candies) > 20
AttributeError: 'Kid' object has no attribute 'candies'
----------------------------------------------------------------------
Ran 12 tests in 0.001s
FAILED (errors=2)
06.11.2023 14:13
06.11.2023 14:17