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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|