1from collections import defaultdict
2import math
3
4
5class Candy:
6 def __init__(self, mass, uranium):
7 self.mass = mass
8 self.uranium = uranium
9
10 def get_mass(self):
11 return self.mass
12
13 def get_uranium_quantity(self):
14 return self.mass * self.uranium
15
16
17class Person:
18 _basket = set()
19
20 def __init__(self, position):
21 self.position = position
22
23 def get_position(self):
24 return self.position
25
26 def set_position(self, new_position):
27 self.position = new_position
28
29
30class Kid(Person):
31 hosts_visited = set()
32
33 def __init__(self, position, initiative):
34 super().__init__(position)
35 self.initiative = initiative
36
37 def get_initiative(self):
38 return self.initiative
39
40 def add_candy(self, candy):
41 self._basket.add(candy)
42
43 def is_critical(self):
44 return sum(candy.get_mass() for candy in self._basket) > 20
45
46
47class Host(Person):
48 def __init__(self, position, candies):
49 super().__init__(position)
50 self._basket = ({Candy(candy[0], candy[1]) for candy in candies})
51
52 def remove_candy(self, get_candy_to_give):
53 if (len(self._basket)):
54 candy_to_give = get_candy_to_give(self._basket)
55 self._basket.remove(candy_to_give)
56 return candy_to_give
57 else:
58 return None
59
60
61class FluxCapacitor:
62 def __init__(self, participants):
63 self.victim = set()
64 self.kids = set()
65 self.hosts = set()
66
67 for participant in participants:
68 if (isinstance(participant, Kid)):
69 self.kids.add(participant)
70 else:
71 self.hosts.add(participant)
72
73 all_hosts_visited = False
74
75 while (not len(self.victim)) and (not all_hosts_visited):
76 for kid in self.kids:
77 hosts_to_visit = set()
78 for host in self.hosts:
79 if (not host in kid.hosts_visited):
80 hosts_to_visit.add(host)
81
82 if (len(hosts_to_visit)):
83 nearest_host = (min(hosts_to_visit, key=lambda h: math.dist(
84 h.get_position(), kid.get_position())))
85 kid.set_position(nearest_host.get_position())
86 kid.hosts_visited.add(nearest_host)
87 candy_given = (
88 nearest_host.remove_candy(self._biggest_candy))
89 if (candy_given != None):
90 kid.add_candy(candy_given)
91
92 for kid in self.kids:
93 if kid.is_critical():
94 self.victim.add(kid)
95 if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts):
96 all_hosts_visited = True
97
98 def _kid_go_to_nearest_host(self, kid, hosts):
99 hosts_to_visit = set()
100 for host in hosts:
101 if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited):
102 hosts_to_visit.add(host)
103
104 nearest_host = (min(hosts_to_visit, key=lambda h: math.dist(
105 h.get_position(), kid.get_position())))
106
107 kid.set_position(nearest_host.get_position())
108 kid.hosts_visited.add(nearest_host)
109
110 candy_given = nearest_host.remove_candy(self._biggest_candy)
111 if candy_given != None:
112 kid.add_candy(candy_given)
113
114 @staticmethod
115 def _biggest_candy(candies):
116 return max(candies, key=lambda c: c.get_mass())
117
118 def get_victim(self):
119 if len(self.victim):
120 return self.victim
121 return 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 79, in test_empty
flux_capacitor = FluxCapacitor(set())
File "/tmp/solution.py", line 75, in __init__
while (not len(self.victim)) and (not all_hosts_visited):
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 95, in test_empty_kids
flux_capacitor = FluxCapacitor({host1, host2})
File "/tmp/solution.py", line 75, in __init__
while (not len(self.victim)) and (not all_hosts_visited):
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_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())
AssertionError: True is not false
----------------------------------------------------------------------
Ran 12 tests in 0.402s
FAILED (failures=3)
Виктор Бечев
08.11.2023 12:42Жорката спомена на лекцията, но най-честата грешка, която виждам при теб е проверките с `if len(something)...`. `if something` върши същата работа.
|
f | 1 | from collections import defaultdict | f | 1 | from collections import defaultdict |
2 | import math | 2 | import math | ||
3 | 3 | ||||
4 | 4 | ||||
5 | class Candy: | 5 | class Candy: | ||
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_mass(self): | 10 | def get_mass(self): | ||
11 | return self.mass | 11 | return self.mass | ||
12 | 12 | ||||
13 | def get_uranium_quantity(self): | 13 | def get_uranium_quantity(self): | ||
14 | return self.mass * self.uranium | 14 | return self.mass * self.uranium | ||
15 | 15 | ||||
16 | 16 | ||||
17 | class Person: | 17 | class Person: | ||
18 | _basket = set() | 18 | _basket = set() | ||
19 | 19 | ||||
20 | def __init__(self, position): | 20 | def __init__(self, position): | ||
21 | self.position = position | 21 | self.position = position | ||
22 | 22 | ||||
23 | def get_position(self): | 23 | def get_position(self): | ||
24 | return self.position | 24 | return self.position | ||
25 | 25 | ||||
26 | def set_position(self, new_position): | 26 | def set_position(self, new_position): | ||
27 | self.position = new_position | 27 | self.position = new_position | ||
28 | 28 | ||||
29 | 29 | ||||
30 | class Kid(Person): | 30 | class Kid(Person): | ||
31 | hosts_visited = set() | 31 | hosts_visited = set() | ||
32 | 32 | ||||
33 | def __init__(self, position, initiative): | 33 | def __init__(self, position, initiative): | ||
34 | super().__init__(position) | 34 | super().__init__(position) | ||
35 | self.initiative = initiative | 35 | self.initiative = initiative | ||
36 | 36 | ||||
37 | def get_initiative(self): | 37 | def get_initiative(self): | ||
38 | return self.initiative | 38 | return self.initiative | ||
39 | 39 | ||||
40 | def add_candy(self, candy): | 40 | def add_candy(self, candy): | ||
41 | self._basket.add(candy) | 41 | self._basket.add(candy) | ||
42 | 42 | ||||
43 | def is_critical(self): | 43 | def is_critical(self): | ||
44 | return sum(candy.get_mass() for candy in self._basket) > 20 | 44 | return sum(candy.get_mass() for candy in self._basket) > 20 | ||
45 | 45 | ||||
46 | 46 | ||||
47 | class Host(Person): | 47 | class Host(Person): | ||
48 | def __init__(self, position, candies): | 48 | def __init__(self, position, candies): | ||
49 | super().__init__(position) | 49 | super().__init__(position) | ||
50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | 50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | ||
51 | 51 | ||||
52 | def remove_candy(self, get_candy_to_give): | 52 | def remove_candy(self, get_candy_to_give): | ||
53 | if (len(self._basket)): | 53 | if (len(self._basket)): | ||
54 | candy_to_give = get_candy_to_give(self._basket) | 54 | candy_to_give = get_candy_to_give(self._basket) | ||
55 | self._basket.remove(candy_to_give) | 55 | self._basket.remove(candy_to_give) | ||
56 | return candy_to_give | 56 | return candy_to_give | ||
57 | else: | 57 | else: | ||
58 | return None | 58 | return None | ||
59 | 59 | ||||
60 | 60 | ||||
61 | class FluxCapacitor: | 61 | class FluxCapacitor: | ||
62 | def __init__(self, participants): | 62 | def __init__(self, participants): | ||
63 | self.victim = set() | 63 | self.victim = set() | ||
64 | self.kids = set() | 64 | self.kids = set() | ||
65 | self.hosts = set() | 65 | self.hosts = set() | ||
66 | 66 | ||||
67 | for participant in participants: | 67 | for participant in participants: | ||
68 | if (isinstance(participant, Kid)): | 68 | if (isinstance(participant, Kid)): | ||
69 | self.kids.add(participant) | 69 | self.kids.add(participant) | ||
70 | else: | 70 | else: | ||
71 | self.hosts.add(participant) | 71 | self.hosts.add(participant) | ||
72 | 72 | ||||
73 | all_hosts_visited = False | 73 | all_hosts_visited = False | ||
74 | 74 | ||||
75 | while (not len(self.victim)) and (not all_hosts_visited): | 75 | while (not len(self.victim)) and (not all_hosts_visited): | ||
76 | for kid in self.kids: | 76 | for kid in self.kids: | ||
77 | hosts_to_visit = set() | 77 | hosts_to_visit = set() | ||
78 | for host in self.hosts: | 78 | for host in self.hosts: | ||
79 | if (not host in kid.hosts_visited): | 79 | if (not host in kid.hosts_visited): | ||
80 | hosts_to_visit.add(host) | 80 | hosts_to_visit.add(host) | ||
81 | 81 | ||||
82 | if (len(hosts_to_visit)): | 82 | if (len(hosts_to_visit)): | ||
n | 83 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | n | 83 | nearest_host = (min(hosts_to_visit, key=lambda h: math.dist( |
84 | h.get_position(), kid.get_position())) | 84 | h.get_position(), kid.get_position()))) | ||
85 | kid.set_position(nearest_host.get_position()) | 85 | kid.set_position(nearest_host.get_position()) | ||
86 | kid.hosts_visited.add(nearest_host) | 86 | kid.hosts_visited.add(nearest_host) | ||
n | 87 | candy_given = nearest_host.remove_candy( | n | 87 | candy_given = ( |
88 | self._biggest_candy) | 88 | nearest_host.remove_candy(self._biggest_candy)) | ||
89 | if (candy_given != None): | 89 | if (candy_given != None): | ||
90 | kid.add_candy(candy_given) | 90 | kid.add_candy(candy_given) | ||
91 | 91 | ||||
92 | for kid in self.kids: | 92 | for kid in self.kids: | ||
93 | if kid.is_critical(): | 93 | if kid.is_critical(): | ||
94 | self.victim.add(kid) | 94 | self.victim.add(kid) | ||
95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | 95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | ||
96 | all_hosts_visited = True | 96 | all_hosts_visited = True | ||
97 | 97 | ||||
98 | def _kid_go_to_nearest_host(self, kid, hosts): | 98 | def _kid_go_to_nearest_host(self, kid, hosts): | ||
99 | hosts_to_visit = set() | 99 | hosts_to_visit = set() | ||
100 | for host in hosts: | 100 | for host in hosts: | ||
101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | 101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | ||
102 | hosts_to_visit.add(host) | 102 | hosts_to_visit.add(host) | ||
103 | 103 | ||||
n | 104 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | n | 104 | nearest_host = (min(hosts_to_visit, key=lambda h: math.dist( |
105 | h.get_position(), kid.get_position())) | 105 | h.get_position(), kid.get_position()))) | ||
106 | 106 | ||||
107 | kid.set_position(nearest_host.get_position()) | 107 | kid.set_position(nearest_host.get_position()) | ||
108 | kid.hosts_visited.add(nearest_host) | 108 | kid.hosts_visited.add(nearest_host) | ||
109 | 109 | ||||
110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | 110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | ||
n | 111 | if (candy_given != None): | n | 111 | if candy_given != None: |
112 | kid.add_candy(candy_given) | 112 | kid.add_candy(candy_given) | ||
113 | 113 | ||||
114 | @staticmethod | 114 | @staticmethod | ||
115 | def _biggest_candy(candies): | 115 | def _biggest_candy(candies): | ||
116 | return max(candies, key=lambda c: c.get_mass()) | 116 | return max(candies, key=lambda c: c.get_mass()) | ||
117 | 117 | ||||
118 | def get_victim(self): | 118 | def get_victim(self): | ||
t | 119 | if (len(self.victim)): | t | 119 | if len(self.victim): |
120 | return self.victim | 120 | return self.victim | ||
121 | return None | 121 | return None |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | from collections import defaultdict | f | 1 | from collections import defaultdict |
2 | import math | 2 | import math | ||
3 | 3 | ||||
4 | 4 | ||||
5 | class Candy: | 5 | class Candy: | ||
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_mass(self): | 10 | def get_mass(self): | ||
11 | return self.mass | 11 | return self.mass | ||
12 | 12 | ||||
13 | def get_uranium_quantity(self): | 13 | def get_uranium_quantity(self): | ||
14 | return self.mass * self.uranium | 14 | return self.mass * self.uranium | ||
15 | 15 | ||||
16 | 16 | ||||
17 | class Person: | 17 | class Person: | ||
18 | _basket = set() | 18 | _basket = set() | ||
19 | 19 | ||||
20 | def __init__(self, position): | 20 | def __init__(self, position): | ||
21 | self.position = position | 21 | self.position = position | ||
22 | 22 | ||||
23 | def get_position(self): | 23 | def get_position(self): | ||
24 | return self.position | 24 | return self.position | ||
25 | 25 | ||||
26 | def set_position(self, new_position): | 26 | def set_position(self, new_position): | ||
27 | self.position = new_position | 27 | self.position = new_position | ||
28 | 28 | ||||
29 | 29 | ||||
30 | class Kid(Person): | 30 | class Kid(Person): | ||
31 | hosts_visited = set() | 31 | hosts_visited = set() | ||
32 | 32 | ||||
33 | def __init__(self, position, initiative): | 33 | def __init__(self, position, initiative): | ||
34 | super().__init__(position) | 34 | super().__init__(position) | ||
35 | self.initiative = initiative | 35 | self.initiative = initiative | ||
36 | 36 | ||||
37 | def get_initiative(self): | 37 | def get_initiative(self): | ||
38 | return self.initiative | 38 | return self.initiative | ||
39 | 39 | ||||
40 | def add_candy(self, candy): | 40 | def add_candy(self, candy): | ||
41 | self._basket.add(candy) | 41 | self._basket.add(candy) | ||
42 | 42 | ||||
43 | def is_critical(self): | 43 | def is_critical(self): | ||
44 | return sum(candy.get_mass() for candy in self._basket) > 20 | 44 | return sum(candy.get_mass() for candy in self._basket) > 20 | ||
45 | 45 | ||||
46 | 46 | ||||
47 | class Host(Person): | 47 | class Host(Person): | ||
48 | def __init__(self, position, candies): | 48 | def __init__(self, position, candies): | ||
49 | super().__init__(position) | 49 | super().__init__(position) | ||
50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | 50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | ||
51 | 51 | ||||
52 | def remove_candy(self, get_candy_to_give): | 52 | def remove_candy(self, get_candy_to_give): | ||
53 | if (len(self._basket)): | 53 | if (len(self._basket)): | ||
54 | candy_to_give = get_candy_to_give(self._basket) | 54 | candy_to_give = get_candy_to_give(self._basket) | ||
55 | self._basket.remove(candy_to_give) | 55 | self._basket.remove(candy_to_give) | ||
56 | return candy_to_give | 56 | return candy_to_give | ||
57 | else: | 57 | else: | ||
58 | return None | 58 | return None | ||
59 | 59 | ||||
60 | 60 | ||||
61 | class FluxCapacitor: | 61 | class FluxCapacitor: | ||
62 | def __init__(self, participants): | 62 | def __init__(self, participants): | ||
63 | self.victim = set() | 63 | self.victim = set() | ||
64 | self.kids = set() | 64 | self.kids = set() | ||
65 | self.hosts = set() | 65 | self.hosts = set() | ||
66 | 66 | ||||
67 | for participant in participants: | 67 | for participant in participants: | ||
68 | if (isinstance(participant, Kid)): | 68 | if (isinstance(participant, Kid)): | ||
69 | self.kids.add(participant) | 69 | self.kids.add(participant) | ||
70 | else: | 70 | else: | ||
71 | self.hosts.add(participant) | 71 | self.hosts.add(participant) | ||
72 | 72 | ||||
73 | all_hosts_visited = False | 73 | all_hosts_visited = False | ||
74 | 74 | ||||
75 | while (not len(self.victim)) and (not all_hosts_visited): | 75 | while (not len(self.victim)) and (not all_hosts_visited): | ||
76 | for kid in self.kids: | 76 | for kid in self.kids: | ||
77 | hosts_to_visit = set() | 77 | hosts_to_visit = set() | ||
78 | for host in self.hosts: | 78 | for host in self.hosts: | ||
t | 79 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | t | 79 | if (not host in kid.hosts_visited): |
80 | hosts_to_visit.add(host) | 80 | hosts_to_visit.add(host) | ||
81 | 81 | ||||
82 | if (len(hosts_to_visit)): | 82 | if (len(hosts_to_visit)): | ||
83 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | 83 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | ||
84 | h.get_position(), kid.get_position())) | 84 | h.get_position(), kid.get_position())) | ||
85 | kid.set_position(nearest_host.get_position()) | 85 | kid.set_position(nearest_host.get_position()) | ||
86 | kid.hosts_visited.add(nearest_host) | 86 | kid.hosts_visited.add(nearest_host) | ||
87 | candy_given = nearest_host.remove_candy( | 87 | candy_given = nearest_host.remove_candy( | ||
88 | self._biggest_candy) | 88 | self._biggest_candy) | ||
89 | if (candy_given != None): | 89 | if (candy_given != None): | ||
90 | kid.add_candy(candy_given) | 90 | kid.add_candy(candy_given) | ||
91 | 91 | ||||
92 | for kid in self.kids: | 92 | for kid in self.kids: | ||
93 | if kid.is_critical(): | 93 | if kid.is_critical(): | ||
94 | self.victim.add(kid) | 94 | self.victim.add(kid) | ||
95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | 95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | ||
96 | all_hosts_visited = True | 96 | all_hosts_visited = True | ||
97 | 97 | ||||
98 | def _kid_go_to_nearest_host(self, kid, hosts): | 98 | def _kid_go_to_nearest_host(self, kid, hosts): | ||
99 | hosts_to_visit = set() | 99 | hosts_to_visit = set() | ||
100 | for host in hosts: | 100 | for host in hosts: | ||
101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | 101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | ||
102 | hosts_to_visit.add(host) | 102 | hosts_to_visit.add(host) | ||
103 | 103 | ||||
104 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | 104 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | ||
105 | h.get_position(), kid.get_position())) | 105 | h.get_position(), kid.get_position())) | ||
106 | 106 | ||||
107 | kid.set_position(nearest_host.get_position()) | 107 | kid.set_position(nearest_host.get_position()) | ||
108 | kid.hosts_visited.add(nearest_host) | 108 | kid.hosts_visited.add(nearest_host) | ||
109 | 109 | ||||
110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | 110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | ||
111 | if (candy_given != None): | 111 | if (candy_given != None): | ||
112 | kid.add_candy(candy_given) | 112 | kid.add_candy(candy_given) | ||
113 | 113 | ||||
114 | @staticmethod | 114 | @staticmethod | ||
115 | def _biggest_candy(candies): | 115 | def _biggest_candy(candies): | ||
116 | return max(candies, key=lambda c: c.get_mass()) | 116 | return max(candies, key=lambda c: c.get_mass()) | ||
117 | 117 | ||||
118 | def get_victim(self): | 118 | def get_victim(self): | ||
119 | if (len(self.victim)): | 119 | if (len(self.victim)): | ||
120 | return self.victim | 120 | return self.victim | ||
121 | return None | 121 | return None |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
t | 1 | from collections import defaultdict | t | 1 | from collections import defaultdict |
2 | import math | 2 | import math | ||
3 | 3 | ||||
4 | 4 | ||||
5 | class Candy: | 5 | class Candy: | ||
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_mass(self): | 10 | def get_mass(self): | ||
11 | return self.mass | 11 | return self.mass | ||
12 | 12 | ||||
13 | def get_uranium_quantity(self): | 13 | def get_uranium_quantity(self): | ||
14 | return self.mass * self.uranium | 14 | return self.mass * self.uranium | ||
15 | 15 | ||||
16 | 16 | ||||
17 | class Person: | 17 | class Person: | ||
18 | _basket = set() | 18 | _basket = set() | ||
19 | 19 | ||||
20 | def __init__(self, position): | 20 | def __init__(self, position): | ||
21 | self.position = position | 21 | self.position = position | ||
22 | 22 | ||||
23 | def get_position(self): | 23 | def get_position(self): | ||
24 | return self.position | 24 | return self.position | ||
25 | 25 | ||||
26 | def set_position(self, new_position): | 26 | def set_position(self, new_position): | ||
27 | self.position = new_position | 27 | self.position = new_position | ||
28 | 28 | ||||
29 | 29 | ||||
30 | class Kid(Person): | 30 | class Kid(Person): | ||
31 | hosts_visited = set() | 31 | hosts_visited = set() | ||
32 | 32 | ||||
33 | def __init__(self, position, initiative): | 33 | def __init__(self, position, initiative): | ||
34 | super().__init__(position) | 34 | super().__init__(position) | ||
35 | self.initiative = initiative | 35 | self.initiative = initiative | ||
36 | 36 | ||||
37 | def get_initiative(self): | 37 | def get_initiative(self): | ||
38 | return self.initiative | 38 | return self.initiative | ||
39 | 39 | ||||
40 | def add_candy(self, candy): | 40 | def add_candy(self, candy): | ||
41 | self._basket.add(candy) | 41 | self._basket.add(candy) | ||
42 | 42 | ||||
43 | def is_critical(self): | 43 | def is_critical(self): | ||
44 | return sum(candy.get_mass() for candy in self._basket) > 20 | 44 | return sum(candy.get_mass() for candy in self._basket) > 20 | ||
45 | 45 | ||||
46 | 46 | ||||
47 | class Host(Person): | 47 | class Host(Person): | ||
48 | def __init__(self, position, candies): | 48 | def __init__(self, position, candies): | ||
49 | super().__init__(position) | 49 | super().__init__(position) | ||
50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | 50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | ||
51 | 51 | ||||
52 | def remove_candy(self, get_candy_to_give): | 52 | def remove_candy(self, get_candy_to_give): | ||
53 | if (len(self._basket)): | 53 | if (len(self._basket)): | ||
54 | candy_to_give = get_candy_to_give(self._basket) | 54 | candy_to_give = get_candy_to_give(self._basket) | ||
55 | self._basket.remove(candy_to_give) | 55 | self._basket.remove(candy_to_give) | ||
56 | return candy_to_give | 56 | return candy_to_give | ||
57 | else: | 57 | else: | ||
58 | return None | 58 | return None | ||
59 | 59 | ||||
60 | 60 | ||||
61 | class FluxCapacitor: | 61 | class FluxCapacitor: | ||
62 | def __init__(self, participants): | 62 | def __init__(self, participants): | ||
63 | self.victim = set() | 63 | self.victim = set() | ||
64 | self.kids = set() | 64 | self.kids = set() | ||
65 | self.hosts = set() | 65 | self.hosts = set() | ||
66 | 66 | ||||
67 | for participant in participants: | 67 | for participant in participants: | ||
68 | if (isinstance(participant, Kid)): | 68 | if (isinstance(participant, Kid)): | ||
69 | self.kids.add(participant) | 69 | self.kids.add(participant) | ||
70 | else: | 70 | else: | ||
71 | self.hosts.add(participant) | 71 | self.hosts.add(participant) | ||
72 | 72 | ||||
73 | all_hosts_visited = False | 73 | all_hosts_visited = False | ||
74 | 74 | ||||
75 | while (not len(self.victim)) and (not all_hosts_visited): | 75 | while (not len(self.victim)) and (not all_hosts_visited): | ||
76 | for kid in self.kids: | 76 | for kid in self.kids: | ||
77 | hosts_to_visit = set() | 77 | hosts_to_visit = set() | ||
78 | for host in self.hosts: | 78 | for host in self.hosts: | ||
79 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | 79 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | ||
80 | hosts_to_visit.add(host) | 80 | hosts_to_visit.add(host) | ||
81 | 81 | ||||
82 | if (len(hosts_to_visit)): | 82 | if (len(hosts_to_visit)): | ||
83 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | 83 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | ||
84 | h.get_position(), kid.get_position())) | 84 | h.get_position(), kid.get_position())) | ||
85 | kid.set_position(nearest_host.get_position()) | 85 | kid.set_position(nearest_host.get_position()) | ||
86 | kid.hosts_visited.add(nearest_host) | 86 | kid.hosts_visited.add(nearest_host) | ||
87 | candy_given = nearest_host.remove_candy( | 87 | candy_given = nearest_host.remove_candy( | ||
88 | self._biggest_candy) | 88 | self._biggest_candy) | ||
89 | if (candy_given != None): | 89 | if (candy_given != None): | ||
90 | kid.add_candy(candy_given) | 90 | kid.add_candy(candy_given) | ||
91 | 91 | ||||
92 | for kid in self.kids: | 92 | for kid in self.kids: | ||
93 | if kid.is_critical(): | 93 | if kid.is_critical(): | ||
94 | self.victim.add(kid) | 94 | self.victim.add(kid) | ||
95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | 95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | ||
96 | all_hosts_visited = True | 96 | all_hosts_visited = True | ||
97 | 97 | ||||
98 | def _kid_go_to_nearest_host(self, kid, hosts): | 98 | def _kid_go_to_nearest_host(self, kid, hosts): | ||
99 | hosts_to_visit = set() | 99 | hosts_to_visit = set() | ||
100 | for host in hosts: | 100 | for host in hosts: | ||
101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | 101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | ||
102 | hosts_to_visit.add(host) | 102 | hosts_to_visit.add(host) | ||
103 | 103 | ||||
104 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | 104 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | ||
105 | h.get_position(), kid.get_position())) | 105 | h.get_position(), kid.get_position())) | ||
106 | 106 | ||||
107 | kid.set_position(nearest_host.get_position()) | 107 | kid.set_position(nearest_host.get_position()) | ||
108 | kid.hosts_visited.add(nearest_host) | 108 | kid.hosts_visited.add(nearest_host) | ||
109 | 109 | ||||
110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | 110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | ||
111 | if (candy_given != None): | 111 | if (candy_given != None): | ||
112 | kid.add_candy(candy_given) | 112 | kid.add_candy(candy_given) | ||
113 | 113 | ||||
114 | @staticmethod | 114 | @staticmethod | ||
115 | def _biggest_candy(candies): | 115 | def _biggest_candy(candies): | ||
116 | return max(candies, key=lambda c: c.get_mass()) | 116 | return max(candies, key=lambda c: c.get_mass()) | ||
117 | 117 | ||||
118 | def get_victim(self): | 118 | def get_victim(self): | ||
119 | if (len(self.victim)): | 119 | if (len(self.victim)): | ||
120 | return self.victim | 120 | return self.victim | ||
121 | return None | 121 | return None |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | from collections import defaultdict | f | 1 | from collections import defaultdict |
2 | import math | 2 | import math | ||
3 | 3 | ||||
4 | 4 | ||||
5 | class Candy: | 5 | class Candy: | ||
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_mass(self): | 10 | def get_mass(self): | ||
11 | return self.mass | 11 | return self.mass | ||
12 | 12 | ||||
13 | def get_uranium_quantity(self): | 13 | def get_uranium_quantity(self): | ||
14 | return self.mass * self.uranium | 14 | return self.mass * self.uranium | ||
15 | 15 | ||||
16 | 16 | ||||
17 | class Person: | 17 | class Person: | ||
18 | _basket = set() | 18 | _basket = set() | ||
19 | 19 | ||||
20 | def __init__(self, position): | 20 | def __init__(self, position): | ||
21 | self.position = position | 21 | self.position = position | ||
22 | 22 | ||||
23 | def get_position(self): | 23 | def get_position(self): | ||
24 | return self.position | 24 | return self.position | ||
25 | 25 | ||||
26 | def set_position(self, new_position): | 26 | def set_position(self, new_position): | ||
27 | self.position = new_position | 27 | self.position = new_position | ||
28 | 28 | ||||
29 | 29 | ||||
30 | class Kid(Person): | 30 | class Kid(Person): | ||
31 | hosts_visited = set() | 31 | hosts_visited = set() | ||
32 | 32 | ||||
33 | def __init__(self, position, initiative): | 33 | def __init__(self, position, initiative): | ||
34 | super().__init__(position) | 34 | super().__init__(position) | ||
35 | self.initiative = initiative | 35 | self.initiative = initiative | ||
36 | 36 | ||||
37 | def get_initiative(self): | 37 | def get_initiative(self): | ||
38 | return self.initiative | 38 | return self.initiative | ||
39 | 39 | ||||
40 | def add_candy(self, candy): | 40 | def add_candy(self, candy): | ||
41 | self._basket.add(candy) | 41 | self._basket.add(candy) | ||
42 | 42 | ||||
43 | def is_critical(self): | 43 | def is_critical(self): | ||
44 | return sum(candy.get_mass() for candy in self._basket) > 20 | 44 | return sum(candy.get_mass() for candy in self._basket) > 20 | ||
45 | 45 | ||||
46 | 46 | ||||
47 | class Host(Person): | 47 | class Host(Person): | ||
48 | def __init__(self, position, candies): | 48 | def __init__(self, position, candies): | ||
49 | super().__init__(position) | 49 | super().__init__(position) | ||
50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | 50 | self._basket = ({Candy(candy[0], candy[1]) for candy in candies}) | ||
51 | 51 | ||||
52 | def remove_candy(self, get_candy_to_give): | 52 | def remove_candy(self, get_candy_to_give): | ||
53 | if (len(self._basket)): | 53 | if (len(self._basket)): | ||
54 | candy_to_give = get_candy_to_give(self._basket) | 54 | candy_to_give = get_candy_to_give(self._basket) | ||
55 | self._basket.remove(candy_to_give) | 55 | self._basket.remove(candy_to_give) | ||
56 | return candy_to_give | 56 | return candy_to_give | ||
57 | else: | 57 | else: | ||
58 | return None | 58 | return None | ||
59 | 59 | ||||
60 | 60 | ||||
61 | class FluxCapacitor: | 61 | class FluxCapacitor: | ||
62 | def __init__(self, participants): | 62 | def __init__(self, participants): | ||
63 | self.victim = set() | 63 | self.victim = set() | ||
64 | self.kids = set() | 64 | self.kids = set() | ||
65 | self.hosts = set() | 65 | self.hosts = set() | ||
66 | 66 | ||||
67 | for participant in participants: | 67 | for participant in participants: | ||
68 | if (isinstance(participant, Kid)): | 68 | if (isinstance(participant, Kid)): | ||
69 | self.kids.add(participant) | 69 | self.kids.add(participant) | ||
70 | else: | 70 | else: | ||
71 | self.hosts.add(participant) | 71 | self.hosts.add(participant) | ||
72 | 72 | ||||
73 | all_hosts_visited = False | 73 | all_hosts_visited = False | ||
74 | 74 | ||||
75 | while (not len(self.victim)) and (not all_hosts_visited): | 75 | while (not len(self.victim)) and (not all_hosts_visited): | ||
76 | for kid in self.kids: | 76 | for kid in self.kids: | ||
77 | hosts_to_visit = set() | 77 | hosts_to_visit = set() | ||
78 | for host in self.hosts: | 78 | for host in self.hosts: | ||
79 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | 79 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | ||
80 | hosts_to_visit.add(host) | 80 | hosts_to_visit.add(host) | ||
81 | 81 | ||||
t | t | 82 | if (len(hosts_to_visit)): | ||
82 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | 83 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | ||
83 | h.get_position(), kid.get_position())) | 84 | h.get_position(), kid.get_position())) | ||
84 | kid.set_position(nearest_host.get_position()) | 85 | kid.set_position(nearest_host.get_position()) | ||
85 | kid.hosts_visited.add(nearest_host) | 86 | kid.hosts_visited.add(nearest_host) | ||
86 | candy_given = nearest_host.remove_candy(self._biggest_candy) | 87 | candy_given = nearest_host.remove_candy( | ||
88 | self._biggest_candy) | ||||
87 | if (candy_given != None): | 89 | if (candy_given != None): | ||
88 | kid.add_candy(candy_given) | 90 | kid.add_candy(candy_given) | ||
89 | 91 | ||||
90 | for kid in self.kids: | 92 | for kid in self.kids: | ||
91 | if kid.is_critical(): | 93 | if kid.is_critical(): | ||
92 | self.victim.add(kid) | 94 | self.victim.add(kid) | ||
93 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | 95 | if (not all_hosts_visited) and len(kid.hosts_visited) == len(self.hosts): | ||
94 | all_hosts_visited = True | 96 | all_hosts_visited = True | ||
95 | 97 | ||||
96 | def _kid_go_to_nearest_host(self, kid, hosts): | 98 | def _kid_go_to_nearest_host(self, kid, hosts): | ||
97 | hosts_to_visit = set() | 99 | hosts_to_visit = set() | ||
98 | for host in hosts: | 100 | for host in hosts: | ||
99 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | 101 | if (host.get_position() != kid.get_position()) and (not host in kid.hosts_visited): | ||
100 | hosts_to_visit.add(host) | 102 | hosts_to_visit.add(host) | ||
101 | 103 | ||||
102 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | 104 | nearest_host = min(hosts_to_visit, key=lambda h: math.dist( | ||
103 | h.get_position(), kid.get_position())) | 105 | h.get_position(), kid.get_position())) | ||
104 | 106 | ||||
105 | kid.set_position(nearest_host.get_position()) | 107 | kid.set_position(nearest_host.get_position()) | ||
106 | kid.hosts_visited.add(nearest_host) | 108 | kid.hosts_visited.add(nearest_host) | ||
107 | 109 | ||||
108 | candy_given = nearest_host.remove_candy(self._biggest_candy) | 110 | candy_given = nearest_host.remove_candy(self._biggest_candy) | ||
109 | if (candy_given != None): | 111 | if (candy_given != None): | ||
110 | kid.add_candy(candy_given) | 112 | kid.add_candy(candy_given) | ||
111 | 113 | ||||
112 | @staticmethod | 114 | @staticmethod | ||
113 | def _biggest_candy(candies): | 115 | def _biggest_candy(candies): | ||
114 | return max(candies, key=lambda c: c.get_mass()) | 116 | return max(candies, key=lambda c: c.get_mass()) | ||
115 | 117 | ||||
116 | def get_victim(self): | 118 | def get_victim(self): | ||
117 | if (len(self.victim)): | 119 | if (len(self.victim)): | ||
118 | return self.victim | 120 | return self.victim | ||
119 | return None | 121 | return None |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
08.11.2023 12:41
08.11.2023 12:44