1import math
2
3
4class Candy:
5
6 def __init__(self, mass, uranium):
7 self.mass = mass
8 self.uranium = uranium
9
10 def get_uranium_quantity(self):
11 return self.mass * self.uranium
12
13 def get_mass(self):
14 return self.mass
15
16
17class Person:
18
19 def __init__(self, position):
20 self.position = position
21
22 def get_position(self):
23 return self.position
24
25 def set_position(self, new_position):
26 self.position = new_position
27
28
29class Kid(Person):
30
31 LETHAL_DOSE = 20
32
33 def __init__(self, position, initiative):
34 super().__init__(position)
35 self.initiative = initiative
36 # we will store the kid`s candy in a list named basket
37 self.basket = []
38 self.visited = []
39
40 def get_initiative(self):
41 return self.initiative
42
43 def add_candy(self, candy):
44 self.basket.append(candy)
45
46 def is_critical(self):
47 total_uranium_quantity = 0
48 for candy_item in self.basket:
49 total_uranium_quantity += candy_item.get_uranium_quantity()
50
51 return total_uranium_quantity > self.LETHAL_DOSE
52
53
54class Host(Person):
55
56 def __init__(self, position, candies):
57 super().__init__(position)
58 self.candies = [Candy(mass, uranium) for mass, uranium in candies]
59
60 def choose_candy(self, candies):
61 return max(candies, key=lambda candy: candy.get_mass())
62
63 def remove_candy(self, choose_candy_func):
64 if len(self.candies) == 0:
65 return None
66
67 choosen_candy = choose_candy_func(self.candies)
68 self.candies.remove(choosen_candy)
69 return choosen_candy
70
71
72class FluxCapacitor:
73
74 def __init__(self, participants):
75 self.participants = participants
76 self.hosts = []
77 self.kids = []
78 for participant in self.participants:
79 if isinstance(participant, Host):
80 self.hosts.append(participant)
81 elif isinstance(participant, Kid):
82 self.kids.append(participant)
83
84 self.kids = sorted(self.kids, key=lambda kid: kid.get_initiative())
85
86 def get_victim(self):
87 dead_kids = []
88 is_dead = False
89 while not is_dead:
90 kid: Kid
91 for kid in self.kids:
92 current_host = None
93 current_dist = float('inf')
94 host: Host
95 for host in self.hosts:
96 if host in kid.visited:
97 continue
98 distance = math.dist(kid.get_position(), host.get_position())
99 if distance < current_dist:
100 current_dist = distance
101 current_host = host
102 elif current_dist == distance and host.get_position() < current_host.get_position():
103 current_dist = distance
104 current_host = host
105
106 if current_host == None:
107 is_dead = True
108 break
109
110 kid.visited.append(current_host)
111 picked_candy = current_host.remove_candy(host.choose_candy)
112
113 if picked_candy is not None:
114 kid.basket.append(picked_candy)
115
116 if kid.is_critical():
117 is_dead = True
118 dead_kids.append(kid)
119
120 return dead_kids or None
.F.F.F......
======================================================================
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 89, in get_victim
while not is_dead:
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 89, in get_victim
while not is_dead:
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_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})
AssertionError: [<solution.Kid object at 0x7fbdb615c5b0>,[36 chars]fd0>] != {<solution.Kid object at 0x7fbdb615c5b0>,[36 chars]fd0>}
----------------------------------------------------------------------
Ran 12 tests in 0.402s
FAILED (failures=3)
| f | 1 | import math | f | 1 | import math |
| 2 | 2 | ||||
| 3 | 3 | ||||
| 4 | class Candy: | 4 | class Candy: | ||
| 5 | 5 | ||||
| 6 | def __init__(self, mass, uranium): | 6 | def __init__(self, mass, uranium): | ||
| 7 | self.mass = mass | 7 | self.mass = mass | ||
| 8 | self.uranium = uranium | 8 | self.uranium = uranium | ||
| 9 | 9 | ||||
| 10 | def get_uranium_quantity(self): | 10 | def get_uranium_quantity(self): | ||
| 11 | return self.mass * self.uranium | 11 | return self.mass * self.uranium | ||
| 12 | 12 | ||||
| 13 | def get_mass(self): | 13 | def get_mass(self): | ||
| 14 | return self.mass | 14 | return self.mass | ||
| 15 | 15 | ||||
| 16 | 16 | ||||
| 17 | class Person: | 17 | class Person: | ||
| 18 | 18 | ||||
| 19 | def __init__(self, position): | 19 | def __init__(self, position): | ||
| 20 | self.position = position | 20 | self.position = position | ||
| 21 | 21 | ||||
| 22 | def get_position(self): | 22 | def get_position(self): | ||
| 23 | return self.position | 23 | return self.position | ||
| 24 | 24 | ||||
| 25 | def set_position(self, new_position): | 25 | def set_position(self, new_position): | ||
| 26 | self.position = new_position | 26 | self.position = new_position | ||
| 27 | 27 | ||||
| 28 | 28 | ||||
| 29 | class Kid(Person): | 29 | class Kid(Person): | ||
| 30 | 30 | ||||
| n | n | 31 | LETHAL_DOSE = 20 | ||
| 32 | |||||
| 31 | def __init__(self, position, initiative): | 33 | def __init__(self, position, initiative): | ||
| 32 | super().__init__(position) | 34 | super().__init__(position) | ||
| 33 | self.initiative = initiative | 35 | self.initiative = initiative | ||
| 34 | # we will store the kid`s candy in a list named basket | 36 | # we will store the kid`s candy in a list named basket | ||
| 35 | self.basket = [] | 37 | self.basket = [] | ||
| 36 | self.visited = [] | 38 | self.visited = [] | ||
| 37 | 39 | ||||
| 38 | def get_initiative(self): | 40 | def get_initiative(self): | ||
| 39 | return self.initiative | 41 | return self.initiative | ||
| 40 | 42 | ||||
| 41 | def add_candy(self, candy): | 43 | def add_candy(self, candy): | ||
| 42 | self.basket.append(candy) | 44 | self.basket.append(candy) | ||
| 43 | 45 | ||||
| 44 | def is_critical(self): | 46 | def is_critical(self): | ||
| 45 | total_uranium_quantity = 0 | 47 | total_uranium_quantity = 0 | ||
| 46 | for candy_item in self.basket: | 48 | for candy_item in self.basket: | ||
| 47 | total_uranium_quantity += candy_item.get_uranium_quantity() | 49 | total_uranium_quantity += candy_item.get_uranium_quantity() | ||
| 48 | 50 | ||||
| n | 49 | return total_uranium_quantity > 20 | n | 51 | return total_uranium_quantity > self.LETHAL_DOSE |
| 50 | 52 | ||||
| 51 | 53 | ||||
| 52 | class Host(Person): | 54 | class Host(Person): | ||
| 53 | 55 | ||||
| 54 | def __init__(self, position, candies): | 56 | def __init__(self, position, candies): | ||
| 55 | super().__init__(position) | 57 | super().__init__(position) | ||
| 56 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 58 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
| 57 | 59 | ||||
| 58 | def choose_candy(self, candies): | 60 | def choose_candy(self, candies): | ||
| 59 | return max(candies, key=lambda candy: candy.get_mass()) | 61 | return max(candies, key=lambda candy: candy.get_mass()) | ||
| 60 | 62 | ||||
| 61 | def remove_candy(self, choose_candy_func): | 63 | def remove_candy(self, choose_candy_func): | ||
| 62 | if len(self.candies) == 0: | 64 | if len(self.candies) == 0: | ||
| 63 | return None | 65 | return None | ||
| 64 | 66 | ||||
| 65 | choosen_candy = choose_candy_func(self.candies) | 67 | choosen_candy = choose_candy_func(self.candies) | ||
| 66 | self.candies.remove(choosen_candy) | 68 | self.candies.remove(choosen_candy) | ||
| 67 | return choosen_candy | 69 | return choosen_candy | ||
| 68 | 70 | ||||
| 69 | 71 | ||||
| 70 | class FluxCapacitor: | 72 | class FluxCapacitor: | ||
| 71 | 73 | ||||
| 72 | def __init__(self, participants): | 74 | def __init__(self, participants): | ||
| 73 | self.participants = participants | 75 | self.participants = participants | ||
| 74 | self.hosts = [] | 76 | self.hosts = [] | ||
| 75 | self.kids = [] | 77 | self.kids = [] | ||
| 76 | for participant in self.participants: | 78 | for participant in self.participants: | ||
| 77 | if isinstance(participant, Host): | 79 | if isinstance(participant, Host): | ||
| 78 | self.hosts.append(participant) | 80 | self.hosts.append(participant) | ||
| 79 | elif isinstance(participant, Kid): | 81 | elif isinstance(participant, Kid): | ||
| 80 | self.kids.append(participant) | 82 | self.kids.append(participant) | ||
| 81 | 83 | ||||
| n | 82 | self.kids = sorted(self.kids, key = lambda kid: kid.get_initiative()) | n | 84 | self.kids = sorted(self.kids, key=lambda kid: kid.get_initiative()) |
| 83 | 85 | ||||
| 84 | def get_victim(self): | 86 | def get_victim(self): | ||
| 85 | dead_kids = [] | 87 | dead_kids = [] | ||
| 86 | is_dead = False | 88 | is_dead = False | ||
| 87 | while not is_dead: | 89 | while not is_dead: | ||
| 88 | kid: Kid | 90 | kid: Kid | ||
| 89 | for kid in self.kids: | 91 | for kid in self.kids: | ||
| 90 | current_host = None | 92 | current_host = None | ||
| 91 | current_dist = float('inf') | 93 | current_dist = float('inf') | ||
| 92 | host: Host | 94 | host: Host | ||
| 93 | for host in self.hosts: | 95 | for host in self.hosts: | ||
| 94 | if host in kid.visited: | 96 | if host in kid.visited: | ||
| 95 | continue | 97 | continue | ||
| 96 | distance = math.dist(kid.get_position(), host.get_position()) | 98 | distance = math.dist(kid.get_position(), host.get_position()) | ||
| 97 | if distance < current_dist: | 99 | if distance < current_dist: | ||
| 98 | current_dist = distance | 100 | current_dist = distance | ||
| 99 | current_host = host | 101 | current_host = host | ||
| 100 | elif current_dist == distance and host.get_position() < current_host.get_position(): | 102 | elif current_dist == distance and host.get_position() < current_host.get_position(): | ||
| 101 | current_dist = distance | 103 | current_dist = distance | ||
| 102 | current_host = host | 104 | current_host = host | ||
| 103 | 105 | ||||
| 104 | if current_host == None: | 106 | if current_host == None: | ||
| 105 | is_dead = True | 107 | is_dead = True | ||
| 106 | break | 108 | break | ||
| 107 | 109 | ||||
| 108 | kid.visited.append(current_host) | 110 | kid.visited.append(current_host) | ||
| 109 | picked_candy = current_host.remove_candy(host.choose_candy) | 111 | picked_candy = current_host.remove_candy(host.choose_candy) | ||
| 110 | 112 | ||||
| 111 | if picked_candy is not None: | 113 | if picked_candy is not None: | ||
| 112 | kid.basket.append(picked_candy) | 114 | kid.basket.append(picked_candy) | ||
| 113 | 115 | ||||
| 114 | if kid.is_critical(): | 116 | if kid.is_critical(): | ||
| 115 | is_dead = True | 117 | is_dead = True | ||
| 116 | dead_kids.append(kid) | 118 | dead_kids.append(kid) | ||
| 117 | 119 | ||||
| t | 118 | if len(dead_kids) == 0: | t | ||
| 119 | return None | ||||
| 120 | else: | ||||
| 121 | return dead_kids | 120 | return dead_kids or None |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | import math | f | 1 | import math |
| 2 | 2 | ||||
| 3 | 3 | ||||
| 4 | class Candy: | 4 | class Candy: | ||
| 5 | 5 | ||||
| 6 | def __init__(self, mass, uranium): | 6 | def __init__(self, mass, uranium): | ||
| 7 | self.mass = mass | 7 | self.mass = mass | ||
| 8 | self.uranium = uranium | 8 | self.uranium = uranium | ||
| 9 | 9 | ||||
| 10 | def get_uranium_quantity(self): | 10 | def get_uranium_quantity(self): | ||
| 11 | return self.mass * self.uranium | 11 | return self.mass * self.uranium | ||
| 12 | 12 | ||||
| 13 | def get_mass(self): | 13 | def get_mass(self): | ||
| 14 | return self.mass | 14 | return self.mass | ||
| 15 | 15 | ||||
| 16 | 16 | ||||
| 17 | class Person: | 17 | class Person: | ||
| 18 | 18 | ||||
| 19 | def __init__(self, position): | 19 | def __init__(self, position): | ||
| 20 | self.position = position | 20 | self.position = position | ||
| 21 | 21 | ||||
| 22 | def get_position(self): | 22 | def get_position(self): | ||
| 23 | return self.position | 23 | return self.position | ||
| 24 | 24 | ||||
| 25 | def set_position(self, new_position): | 25 | def set_position(self, new_position): | ||
| 26 | self.position = new_position | 26 | self.position = new_position | ||
| 27 | 27 | ||||
| 28 | 28 | ||||
| 29 | class Kid(Person): | 29 | class Kid(Person): | ||
| 30 | 30 | ||||
| 31 | def __init__(self, position, initiative): | 31 | def __init__(self, position, initiative): | ||
| 32 | super().__init__(position) | 32 | super().__init__(position) | ||
| 33 | self.initiative = initiative | 33 | self.initiative = initiative | ||
| 34 | # we will store the kid`s candy in a list named basket | 34 | # we will store the kid`s candy in a list named basket | ||
| 35 | self.basket = [] | 35 | self.basket = [] | ||
| 36 | self.visited = [] | 36 | self.visited = [] | ||
| 37 | 37 | ||||
| 38 | def get_initiative(self): | 38 | def get_initiative(self): | ||
| 39 | return self.initiative | 39 | return self.initiative | ||
| 40 | 40 | ||||
| 41 | def add_candy(self, candy): | 41 | def add_candy(self, candy): | ||
| 42 | self.basket.append(candy) | 42 | self.basket.append(candy) | ||
| 43 | 43 | ||||
| 44 | def is_critical(self): | 44 | def is_critical(self): | ||
| 45 | total_uranium_quantity = 0 | 45 | total_uranium_quantity = 0 | ||
| 46 | for candy_item in self.basket: | 46 | for candy_item in self.basket: | ||
| 47 | total_uranium_quantity += candy_item.get_uranium_quantity() | 47 | total_uranium_quantity += candy_item.get_uranium_quantity() | ||
| 48 | 48 | ||||
| 49 | return total_uranium_quantity > 20 | 49 | return total_uranium_quantity > 20 | ||
| 50 | 50 | ||||
| 51 | 51 | ||||
| 52 | class Host(Person): | 52 | class Host(Person): | ||
| 53 | 53 | ||||
| 54 | def __init__(self, position, candies): | 54 | def __init__(self, position, candies): | ||
| 55 | super().__init__(position) | 55 | super().__init__(position) | ||
| t | 56 | #self.candies = candies | t | ||
| 57 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | 56 | self.candies = [Candy(mass, uranium) for mass, uranium in candies] | ||
| 58 | 57 | ||||
| 59 | def choose_candy(self, candies): | 58 | def choose_candy(self, candies): | ||
| 60 | return max(candies, key=lambda candy: candy.get_mass()) | 59 | return max(candies, key=lambda candy: candy.get_mass()) | ||
| 61 | 60 | ||||
| 62 | def remove_candy(self, choose_candy_func): | 61 | def remove_candy(self, choose_candy_func): | ||
| 63 | if len(self.candies) == 0: | 62 | if len(self.candies) == 0: | ||
| 64 | return None | 63 | return None | ||
| 65 | 64 | ||||
| 66 | choosen_candy = choose_candy_func(self.candies) | 65 | choosen_candy = choose_candy_func(self.candies) | ||
| 67 | self.candies.remove(choosen_candy) | 66 | self.candies.remove(choosen_candy) | ||
| 68 | return choosen_candy | 67 | return choosen_candy | ||
| 69 | 68 | ||||
| 70 | 69 | ||||
| 71 | class FluxCapacitor: | 70 | class FluxCapacitor: | ||
| 72 | 71 | ||||
| 73 | def __init__(self, participants): | 72 | def __init__(self, participants): | ||
| 74 | self.participants = participants | 73 | self.participants = participants | ||
| 75 | self.hosts = [] | 74 | self.hosts = [] | ||
| 76 | self.kids = [] | 75 | self.kids = [] | ||
| 77 | for participant in self.participants: | 76 | for participant in self.participants: | ||
| 78 | if isinstance(participant, Host): | 77 | if isinstance(participant, Host): | ||
| 79 | self.hosts.append(participant) | 78 | self.hosts.append(participant) | ||
| 80 | elif isinstance(participant, Kid): | 79 | elif isinstance(participant, Kid): | ||
| 81 | self.kids.append(participant) | 80 | self.kids.append(participant) | ||
| 82 | 81 | ||||
| 83 | self.kids = sorted(self.kids, key = lambda kid: kid.get_initiative()) | 82 | self.kids = sorted(self.kids, key = lambda kid: kid.get_initiative()) | ||
| 84 | 83 | ||||
| 85 | def get_victim(self): | 84 | def get_victim(self): | ||
| 86 | dead_kids = [] | 85 | dead_kids = [] | ||
| 87 | is_dead = False | 86 | is_dead = False | ||
| 88 | while not is_dead: | 87 | while not is_dead: | ||
| 89 | kid: Kid | 88 | kid: Kid | ||
| 90 | for kid in self.kids: | 89 | for kid in self.kids: | ||
| 91 | current_host = None | 90 | current_host = None | ||
| 92 | current_dist = float('inf') | 91 | current_dist = float('inf') | ||
| 93 | host: Host | 92 | host: Host | ||
| 94 | for host in self.hosts: | 93 | for host in self.hosts: | ||
| 95 | if host in kid.visited: | 94 | if host in kid.visited: | ||
| 96 | continue | 95 | continue | ||
| 97 | distance = math.dist(kid.get_position(), host.get_position()) | 96 | distance = math.dist(kid.get_position(), host.get_position()) | ||
| 98 | if distance < current_dist: | 97 | if distance < current_dist: | ||
| 99 | current_dist = distance | 98 | current_dist = distance | ||
| 100 | current_host = host | 99 | current_host = host | ||
| 101 | elif current_dist == distance and host.get_position() < current_host.get_position(): | 100 | elif current_dist == distance and host.get_position() < current_host.get_position(): | ||
| 102 | current_dist = distance | 101 | current_dist = distance | ||
| 103 | current_host = host | 102 | current_host = host | ||
| 104 | 103 | ||||
| 105 | if current_host == None: | 104 | if current_host == None: | ||
| 106 | is_dead = True | 105 | is_dead = True | ||
| 107 | break | 106 | break | ||
| 108 | 107 | ||||
| 109 | kid.visited.append(current_host) | 108 | kid.visited.append(current_host) | ||
| 110 | picked_candy = current_host.remove_candy(host.choose_candy) | 109 | picked_candy = current_host.remove_candy(host.choose_candy) | ||
| 111 | 110 | ||||
| 112 | if picked_candy is not None: | 111 | if picked_candy is not None: | ||
| 113 | kid.basket.append(picked_candy) | 112 | kid.basket.append(picked_candy) | ||
| 114 | 113 | ||||
| 115 | if kid.is_critical(): | 114 | if kid.is_critical(): | ||
| 116 | is_dead = True | 115 | is_dead = True | ||
| 117 | dead_kids.append(kid) | 116 | dead_kids.append(kid) | ||
| 118 | 117 | ||||
| 119 | if len(dead_kids) == 0: | 118 | if len(dead_kids) == 0: | ||
| 120 | return None | 119 | return None | ||
| 121 | else: | 120 | else: | ||
| 122 | return dead_kids | 121 | return dead_kids |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||