1import operator
2
3class Candy:
4
5 def __init__(self, mass, uranium):
6 self.mass = mass
7 self.uranium = uranium
8
9 def get_uranium_quantity(self):
10 return self.mass * self.uranium
11
12 def get_mass(self):
13 return self.mass
14
15
16class Person:
17
18 def __init__(self, position):
19 self.position = position
20
21 def get_position(self):
22 return self.position
23
24 def set_position(self, new_position):
25 self.position = new_position
26
27
28class Kid(Person):
29
30 CRITICAL_MASS = 20
31
32 def __init__(self, position, initiative):
33 super().__init__(position)
34 self.initiative = initiative
35 self._basket = []
36 self._uranium_sum = 0
37 self.visited_hosts = []
38
39 def get_initiative(self):
40 return self.initiative
41
42 def add_candy(self, candy):
43 self._basket.append(candy)
44
45 def is_critical(self):
46 self._uranium_sum = 0
47 for candy in self._basket:
48 self._uranium_sum += candy.get_uranium_quantity()
49 return self._uranium_sum > self.CRITICAL_MASS
50
51
52class Host(Person):
53
54 def __init__(self, position, candies):
55 super().__init__(position)
56 self._basket = []
57 self.treated_kids = list()
58 self.kids_to_be_treated = list()
59 self.candies = candies
60
61 for candy in self.candies:
62 self._basket.append(Candy(candy[0], candy[1]))
63
64 def remove_candy(self, function):
65 if len(self._basket) == 0:
66 return None
67 else:
68 candy = function(self._basket)
69 self._basket.remove(candy)
70 return candy
71
72
73class FluxCapacitor:
74
75 def split_participants(self):
76 for participant in self.participants:
77 if type(participant) is Kid:
78 self._kids.append(participant)
79 else:
80 self._hosts.append(participant)
81
82 def __init__(self, participants):
83 self.participants = participants
84 self.victims = set()
85 self._kids = []
86 self._hosts = []
87 self.split_participants()
88
89 def give_Candy(self, kid, host):
90 max_mass_candy = 0
91 candy_to_give = Candy(0, 0)
92 for candy in host._basket:
93 if candy.get_mass() > max_mass_candy:
94 max_mass_candy = candy.get_mass()
95 candy_to_give = candy
96
97 if len(host._basket) > 0:
98 kid.add_candy(candy_to_give)
99 host._basket.remove(candy_to_give)
100
101 def take_initiative(self, kid):
102 return kid.get_initiative()
103
104 def order_kids(self, kids, host):
105 kids.sort(key=self.take_initiative, reverse=True)
106 return kids
107
108 def get_distance(self, kid, host):
109 x_kid, y_kid = kid.get_position()
110 x_host, y_host = host.get_position()
111 return abs(x_kid - x_host) + abs(y_kid - y_host)
112
113 def get_nearest_nonvisited_host(self, kid, visited_hosts):
114 all_distances = dict()
115
116 for host in self._hosts:
117 if host not in visited_hosts:
118 current_distance = self.get_distance(kid, host)
119 all_distances[host] = current_distance
120
121 if len(all_distances) != 0:
122 sorted_distances_to_hosts = sorted(all_distances.items(), key = operator.itemgetter(1))
123 min_distance = sorted_distances_to_hosts[0][1]
124 nearest_hosts = [host for host, distance in sorted_distances_to_hosts if distance == min_distance]
125 if len(nearest_hosts) == 1:
126 return nearest_hosts[0]
127 else:
128 sorted_hosts = sorted(nearest_hosts, key = lambda x: (x.get_position()[0], x.get_position()[1]))
129 return sorted_hosts[0]
130 return None
131
132 def set_kid_to_be_treated_by_host(self, kid, host):
133 kid.visited_hosts.append(host)
134 host.treated_kids.append(kid)
135 host.kids_to_be_treated.append(kid)
136 kid.set_position(host.get_position())
137
138 def get_victim(self):
139 kids_that_have_visited_everyone = set()
140 hosts_that_have_treated_everyone = set()
141
142 while len(self.victims) == 0:
143 for kid in self._kids:
144 if len(kid.visited_hosts) == len(self._hosts):
145 kids_that_have_visited_everyone.add(kid)
146 nearest_host = self.get_nearest_nonvisited_host(kid, kid.visited_hosts)
147 if nearest_host != None:
148 self.set_kid_to_be_treated_by_host(kid, nearest_host)
149
150 for host in self._hosts:
151 if len(host.treated_kids) == len(self._kids):
152 hosts_that_have_treated_everyone.add(host)
153 ordered_kids = self.order_kids(host.kids_to_be_treated, host)
154
155 for kid in ordered_kids:
156 self.give_Candy(kid, host)
157 if kid.is_critical():
158 self.victims.add(kid)
159 host.kids_to_be_treated = list()
160
161 if len(self.victims) != 0:
162 break
163 if len(kids_that_have_visited_everyone) == len(self._kids) and len(hosts_that_have_treated_everyone) == len(self._hosts):
164 break
165
166 return self.victims or None
............
----------------------------------------------------------------------
Ran 12 tests in 0.001s
OK
f | 1 | import operator | f | 1 | import operator |
2 | 2 | ||||
n | 3 | class Candy(): | n | 3 | class Candy: |
4 | |||||
4 | def __init__(self, mass, uranium): | 5 | def __init__(self, mass, uranium): | ||
5 | self.mass = mass | 6 | self.mass = mass | ||
6 | self.uranium = uranium | 7 | self.uranium = uranium | ||
7 | 8 | ||||
8 | def get_uranium_quantity(self): | 9 | def get_uranium_quantity(self): | ||
9 | return self.mass * self.uranium | 10 | return self.mass * self.uranium | ||
10 | 11 | ||||
11 | def get_mass(self): | 12 | def get_mass(self): | ||
12 | return self.mass | 13 | return self.mass | ||
13 | 14 | ||||
14 | 15 | ||||
n | 15 | class Person(): | n | 16 | class Person: |
16 | type_of_class = "person" | ||||
17 | 17 | ||||
18 | def __init__(self, position): | 18 | def __init__(self, position): | ||
19 | self.position = position | 19 | self.position = position | ||
20 | 20 | ||||
21 | def get_position(self): | 21 | def get_position(self): | ||
22 | return self.position | 22 | return self.position | ||
23 | 23 | ||||
24 | def set_position(self, new_position): | 24 | def set_position(self, new_position): | ||
25 | self.position = new_position | 25 | self.position = new_position | ||
n | 26 | n | |||
27 | def get_type_of_class(self): | ||||
28 | return self.type_of_class | ||||
29 | 26 | ||||
30 | 27 | ||||
31 | class Kid(Person): | 28 | class Kid(Person): | ||
n | 32 | type_of_class = "kid" | n | 29 | |
30 | CRITICAL_MASS = 20 | ||||
33 | 31 | ||||
34 | def __init__(self, position, initiative): | 32 | def __init__(self, position, initiative): | ||
35 | super().__init__(position) | 33 | super().__init__(position) | ||
36 | self.initiative = initiative | 34 | self.initiative = initiative | ||
37 | self._basket = [] | 35 | self._basket = [] | ||
38 | self._uranium_sum = 0 | 36 | self._uranium_sum = 0 | ||
39 | self.visited_hosts = [] | 37 | self.visited_hosts = [] | ||
40 | 38 | ||||
41 | def get_initiative(self): | 39 | def get_initiative(self): | ||
42 | return self.initiative | 40 | return self.initiative | ||
43 | 41 | ||||
44 | def add_candy(self, candy): | 42 | def add_candy(self, candy): | ||
45 | self._basket.append(candy) | 43 | self._basket.append(candy) | ||
46 | 44 | ||||
47 | def is_critical(self): | 45 | def is_critical(self): | ||
48 | self._uranium_sum = 0 | 46 | self._uranium_sum = 0 | ||
49 | for candy in self._basket: | 47 | for candy in self._basket: | ||
50 | self._uranium_sum += candy.get_uranium_quantity() | 48 | self._uranium_sum += candy.get_uranium_quantity() | ||
n | 51 | return self._uranium_sum > 20 | n | 49 | return self._uranium_sum > self.CRITICAL_MASS |
52 | 50 | ||||
53 | 51 | ||||
54 | class Host(Person): | 52 | class Host(Person): | ||
n | 55 | type_of_class = "host" | n | ||
56 | 53 | ||||
57 | def __init__(self, position, candies): | 54 | def __init__(self, position, candies): | ||
58 | super().__init__(position) | 55 | super().__init__(position) | ||
59 | self._basket = [] | 56 | self._basket = [] | ||
60 | self.treated_kids = list() | 57 | self.treated_kids = list() | ||
61 | self.kids_to_be_treated = list() | 58 | self.kids_to_be_treated = list() | ||
62 | self.candies = candies | 59 | self.candies = candies | ||
n | n | 60 | |||
63 | for candy in self.candies: | 61 | for candy in self.candies: | ||
64 | self._basket.append(Candy(candy[0], candy[1])) | 62 | self._basket.append(Candy(candy[0], candy[1])) | ||
65 | 63 | ||||
66 | def remove_candy(self, function): | 64 | def remove_candy(self, function): | ||
67 | if len(self._basket) == 0: | 65 | if len(self._basket) == 0: | ||
68 | return None | 66 | return None | ||
69 | else: | 67 | else: | ||
70 | candy = function(self._basket) | 68 | candy = function(self._basket) | ||
71 | self._basket.remove(candy) | 69 | self._basket.remove(candy) | ||
72 | return candy | 70 | return candy | ||
73 | 71 | ||||
74 | 72 | ||||
n | 75 | class FluxCapacitor(): | n | 73 | class FluxCapacitor: |
74 | |||||
75 | def split_participants(self): | ||||
76 | for participant in self.participants: | ||||
77 | if type(participant) is Kid: | ||||
78 | self._kids.append(participant) | ||||
79 | else: | ||||
80 | self._hosts.append(participant) | ||||
76 | 81 | ||||
77 | def __init__(self, participants): | 82 | def __init__(self, participants): | ||
78 | self.participants = participants | 83 | self.participants = participants | ||
79 | self.victims = set() | 84 | self.victims = set() | ||
80 | self._kids = [] | 85 | self._kids = [] | ||
81 | self._hosts = [] | 86 | self._hosts = [] | ||
n | 82 | n | |||
83 | def split_participants(self): | 87 | self.split_participants() | ||
84 | for participant in self.participants: | ||||
85 | if participant.get_type_of_class() == "kid": | ||||
86 | self._kids.append(participant) | ||||
87 | else: | ||||
88 | self._hosts.append(participant) | ||||
89 | 88 | ||||
90 | def give_Candy(self, kid, host): | 89 | def give_Candy(self, kid, host): | ||
n | 91 | max_uranium_candy = 0 | n | 90 | max_mass_candy = 0 |
92 | candy_to_give = Candy(0, 0) | 91 | candy_to_give = Candy(0, 0) | ||
93 | for candy in host._basket: | 92 | for candy in host._basket: | ||
n | 94 | if candy.get_uranium_quantity() > max_uranium_candy: | n | 93 | if candy.get_mass() > max_mass_candy: |
95 | max_uranium_candy = candy.get_uranium_quantity() | 94 | max_mass_candy = candy.get_mass() | ||
96 | candy_to_give = candy | 95 | candy_to_give = candy | ||
96 | |||||
97 | if len(host._basket) > 0: | 97 | if len(host._basket) > 0: | ||
98 | kid.add_candy(candy_to_give) | 98 | kid.add_candy(candy_to_give) | ||
99 | host._basket.remove(candy_to_give) | 99 | host._basket.remove(candy_to_give) | ||
100 | 100 | ||||
101 | def take_initiative(self, kid): | 101 | def take_initiative(self, kid): | ||
102 | return kid.get_initiative() | 102 | return kid.get_initiative() | ||
103 | 103 | ||||
104 | def order_kids(self, kids, host): | 104 | def order_kids(self, kids, host): | ||
n | 105 | kids.sort(key = self.take_initiative, reverse = True) | n | 105 | kids.sort(key=self.take_initiative, reverse=True) |
106 | return kids | 106 | return kids | ||
107 | 107 | ||||
108 | def get_distance(self, kid, host): | 108 | def get_distance(self, kid, host): | ||
n | 109 | (x_kid, y_kid) = kid.get_position() | n | 109 | x_kid, y_kid = kid.get_position() |
110 | (x_host, y_host) = host.get_position() | 110 | x_host, y_host = host.get_position() | ||
111 | return abs(x_kid - x_host) + abs(y_kid - y_host) | 111 | return abs(x_kid - x_host) + abs(y_kid - y_host) | ||
112 | 112 | ||||
113 | def get_nearest_nonvisited_host(self, kid, visited_hosts): | 113 | def get_nearest_nonvisited_host(self, kid, visited_hosts): | ||
114 | all_distances = dict() | 114 | all_distances = dict() | ||
115 | 115 | ||||
116 | for host in self._hosts: | 116 | for host in self._hosts: | ||
117 | if host not in visited_hosts: | 117 | if host not in visited_hosts: | ||
118 | current_distance = self.get_distance(kid, host) | 118 | current_distance = self.get_distance(kid, host) | ||
119 | all_distances[host] = current_distance | 119 | all_distances[host] = current_distance | ||
n | n | 120 | |||
120 | if len(all_distances) != 0: | 121 | if len(all_distances) != 0: | ||
121 | sorted_distances_to_hosts = sorted(all_distances.items(), key = operator.itemgetter(1)) | 122 | sorted_distances_to_hosts = sorted(all_distances.items(), key = operator.itemgetter(1)) | ||
122 | min_distance = sorted_distances_to_hosts[0][1] | 123 | min_distance = sorted_distances_to_hosts[0][1] | ||
123 | nearest_hosts = [host for host, distance in sorted_distances_to_hosts if distance == min_distance] | 124 | nearest_hosts = [host for host, distance in sorted_distances_to_hosts if distance == min_distance] | ||
124 | if len(nearest_hosts) == 1: | 125 | if len(nearest_hosts) == 1: | ||
125 | return nearest_hosts[0] | 126 | return nearest_hosts[0] | ||
126 | else: | 127 | else: | ||
127 | sorted_hosts = sorted(nearest_hosts, key = lambda x: (x.get_position()[0], x.get_position()[1])) | 128 | sorted_hosts = sorted(nearest_hosts, key = lambda x: (x.get_position()[0], x.get_position()[1])) | ||
128 | return sorted_hosts[0] | 129 | return sorted_hosts[0] | ||
129 | return None | 130 | return None | ||
130 | 131 | ||||
131 | def set_kid_to_be_treated_by_host(self, kid, host): | 132 | def set_kid_to_be_treated_by_host(self, kid, host): | ||
132 | kid.visited_hosts.append(host) | 133 | kid.visited_hosts.append(host) | ||
133 | host.treated_kids.append(kid) | 134 | host.treated_kids.append(kid) | ||
134 | host.kids_to_be_treated.append(kid) | 135 | host.kids_to_be_treated.append(kid) | ||
135 | kid.set_position(host.get_position()) | 136 | kid.set_position(host.get_position()) | ||
136 | 137 | ||||
137 | def get_victim(self): | 138 | def get_victim(self): | ||
n | 138 | self.split_participants() | n | ||
139 | kids_that_have_visited_everyone = set() | 139 | kids_that_have_visited_everyone = set() | ||
140 | hosts_that_have_treated_everyone = set() | 140 | hosts_that_have_treated_everyone = set() | ||
141 | 141 | ||||
n | 142 | while(len(self.victims) == 0): | n | 142 | while len(self.victims) == 0: |
143 | for kid in self._kids: | 143 | for kid in self._kids: | ||
144 | if len(kid.visited_hosts) == len(self._hosts): | 144 | if len(kid.visited_hosts) == len(self._hosts): | ||
145 | kids_that_have_visited_everyone.add(kid) | 145 | kids_that_have_visited_everyone.add(kid) | ||
146 | nearest_host = self.get_nearest_nonvisited_host(kid, kid.visited_hosts) | 146 | nearest_host = self.get_nearest_nonvisited_host(kid, kid.visited_hosts) | ||
147 | if nearest_host != None: | 147 | if nearest_host != None: | ||
148 | self.set_kid_to_be_treated_by_host(kid, nearest_host) | 148 | self.set_kid_to_be_treated_by_host(kid, nearest_host) | ||
149 | 149 | ||||
150 | for host in self._hosts: | 150 | for host in self._hosts: | ||
151 | if len(host.treated_kids) == len(self._kids): | 151 | if len(host.treated_kids) == len(self._kids): | ||
152 | hosts_that_have_treated_everyone.add(host) | 152 | hosts_that_have_treated_everyone.add(host) | ||
153 | ordered_kids = self.order_kids(host.kids_to_be_treated, host) | 153 | ordered_kids = self.order_kids(host.kids_to_be_treated, host) | ||
154 | 154 | ||||
155 | for kid in ordered_kids: | 155 | for kid in ordered_kids: | ||
156 | self.give_Candy(kid, host) | 156 | self.give_Candy(kid, host) | ||
157 | if kid.is_critical(): | 157 | if kid.is_critical(): | ||
158 | self.victims.add(kid) | 158 | self.victims.add(kid) | ||
159 | host.kids_to_be_treated = list() | 159 | host.kids_to_be_treated = list() | ||
160 | 160 | ||||
161 | if len(self.victims) != 0: | 161 | if len(self.victims) != 0: | ||
162 | break | 162 | break | ||
163 | if len(kids_that_have_visited_everyone) == len(self._kids) and len(hosts_that_have_treated_everyone) == len(self._hosts): | 163 | if len(kids_that_have_visited_everyone) == len(self._kids) and len(hosts_that_have_treated_everyone) == len(self._hosts): | ||
164 | break | 164 | break | ||
t | 165 | t | 165 | ||
166 | if len(self.victims) != 0: | ||||
167 | return self.victims | 166 | return self.victims or None | ||
168 | else: | ||||
169 | return None |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
f | 1 | import operator | f | 1 | import operator |
2 | 2 | ||||
3 | class Candy(): | 3 | class Candy(): | ||
4 | def __init__(self, mass, uranium): | 4 | def __init__(self, mass, uranium): | ||
5 | self.mass = mass | 5 | self.mass = mass | ||
6 | self.uranium = uranium | 6 | self.uranium = uranium | ||
7 | 7 | ||||
8 | def get_uranium_quantity(self): | 8 | def get_uranium_quantity(self): | ||
9 | return self.mass * self.uranium | 9 | return self.mass * self.uranium | ||
10 | 10 | ||||
11 | def get_mass(self): | 11 | def get_mass(self): | ||
12 | return self.mass | 12 | return self.mass | ||
13 | 13 | ||||
14 | 14 | ||||
15 | class Person(): | 15 | class Person(): | ||
16 | type_of_class = "person" | 16 | type_of_class = "person" | ||
17 | 17 | ||||
18 | def __init__(self, position): | 18 | def __init__(self, position): | ||
19 | self.position = position | 19 | self.position = position | ||
20 | 20 | ||||
21 | def get_position(self): | 21 | def get_position(self): | ||
22 | return self.position | 22 | return self.position | ||
23 | 23 | ||||
24 | def set_position(self, new_position): | 24 | def set_position(self, new_position): | ||
25 | self.position = new_position | 25 | self.position = new_position | ||
26 | 26 | ||||
27 | def get_type_of_class(self): | 27 | def get_type_of_class(self): | ||
28 | return self.type_of_class | 28 | return self.type_of_class | ||
29 | 29 | ||||
30 | 30 | ||||
31 | class Kid(Person): | 31 | class Kid(Person): | ||
32 | type_of_class = "kid" | 32 | type_of_class = "kid" | ||
33 | 33 | ||||
34 | def __init__(self, position, initiative): | 34 | def __init__(self, position, initiative): | ||
35 | super().__init__(position) | 35 | super().__init__(position) | ||
36 | self.initiative = initiative | 36 | self.initiative = initiative | ||
37 | self._basket = [] | 37 | self._basket = [] | ||
38 | self._uranium_sum = 0 | 38 | self._uranium_sum = 0 | ||
39 | self.visited_hosts = [] | 39 | self.visited_hosts = [] | ||
40 | 40 | ||||
41 | def get_initiative(self): | 41 | def get_initiative(self): | ||
42 | return self.initiative | 42 | return self.initiative | ||
43 | 43 | ||||
44 | def add_candy(self, candy): | 44 | def add_candy(self, candy): | ||
45 | self._basket.append(candy) | 45 | self._basket.append(candy) | ||
46 | 46 | ||||
47 | def is_critical(self): | 47 | def is_critical(self): | ||
48 | self._uranium_sum = 0 | 48 | self._uranium_sum = 0 | ||
49 | for candy in self._basket: | 49 | for candy in self._basket: | ||
50 | self._uranium_sum += candy.get_uranium_quantity() | 50 | self._uranium_sum += candy.get_uranium_quantity() | ||
51 | return self._uranium_sum > 20 | 51 | return self._uranium_sum > 20 | ||
52 | 52 | ||||
53 | 53 | ||||
54 | class Host(Person): | 54 | class Host(Person): | ||
55 | type_of_class = "host" | 55 | type_of_class = "host" | ||
56 | 56 | ||||
57 | def __init__(self, position, candies): | 57 | def __init__(self, position, candies): | ||
58 | super().__init__(position) | 58 | super().__init__(position) | ||
59 | self._basket = [] | 59 | self._basket = [] | ||
60 | self.treated_kids = list() | 60 | self.treated_kids = list() | ||
61 | self.kids_to_be_treated = list() | 61 | self.kids_to_be_treated = list() | ||
62 | self.candies = candies | 62 | self.candies = candies | ||
63 | for candy in self.candies: | 63 | for candy in self.candies: | ||
64 | self._basket.append(Candy(candy[0], candy[1])) | 64 | self._basket.append(Candy(candy[0], candy[1])) | ||
65 | 65 | ||||
66 | def remove_candy(self, function): | 66 | def remove_candy(self, function): | ||
67 | if len(self._basket) == 0: | 67 | if len(self._basket) == 0: | ||
68 | return None | 68 | return None | ||
69 | else: | 69 | else: | ||
70 | candy = function(self._basket) | 70 | candy = function(self._basket) | ||
71 | self._basket.remove(candy) | 71 | self._basket.remove(candy) | ||
72 | return candy | 72 | return candy | ||
73 | 73 | ||||
74 | 74 | ||||
75 | class FluxCapacitor(): | 75 | class FluxCapacitor(): | ||
76 | 76 | ||||
77 | def __init__(self, participants): | 77 | def __init__(self, participants): | ||
78 | self.participants = participants | 78 | self.participants = participants | ||
79 | self.victims = set() | 79 | self.victims = set() | ||
80 | self._kids = [] | 80 | self._kids = [] | ||
81 | self._hosts = [] | 81 | self._hosts = [] | ||
82 | 82 | ||||
83 | def split_participants(self): | 83 | def split_participants(self): | ||
84 | for participant in self.participants: | 84 | for participant in self.participants: | ||
85 | if participant.get_type_of_class() == "kid": | 85 | if participant.get_type_of_class() == "kid": | ||
86 | self._kids.append(participant) | 86 | self._kids.append(participant) | ||
87 | else: | 87 | else: | ||
88 | self._hosts.append(participant) | 88 | self._hosts.append(participant) | ||
89 | 89 | ||||
90 | def give_Candy(self, kid, host): | 90 | def give_Candy(self, kid, host): | ||
91 | max_uranium_candy = 0 | 91 | max_uranium_candy = 0 | ||
92 | candy_to_give = Candy(0, 0) | 92 | candy_to_give = Candy(0, 0) | ||
93 | for candy in host._basket: | 93 | for candy in host._basket: | ||
94 | if candy.get_uranium_quantity() > max_uranium_candy: | 94 | if candy.get_uranium_quantity() > max_uranium_candy: | ||
95 | max_uranium_candy = candy.get_uranium_quantity() | 95 | max_uranium_candy = candy.get_uranium_quantity() | ||
96 | candy_to_give = candy | 96 | candy_to_give = candy | ||
97 | if len(host._basket) > 0: | 97 | if len(host._basket) > 0: | ||
98 | kid.add_candy(candy_to_give) | 98 | kid.add_candy(candy_to_give) | ||
99 | host._basket.remove(candy_to_give) | 99 | host._basket.remove(candy_to_give) | ||
100 | 100 | ||||
101 | def take_initiative(self, kid): | 101 | def take_initiative(self, kid): | ||
102 | return kid.get_initiative() | 102 | return kid.get_initiative() | ||
103 | 103 | ||||
104 | def order_kids(self, kids, host): | 104 | def order_kids(self, kids, host): | ||
105 | kids.sort(key = self.take_initiative, reverse = True) | 105 | kids.sort(key = self.take_initiative, reverse = True) | ||
106 | return kids | 106 | return kids | ||
107 | 107 | ||||
108 | def get_distance(self, kid, host): | 108 | def get_distance(self, kid, host): | ||
109 | (x_kid, y_kid) = kid.get_position() | 109 | (x_kid, y_kid) = kid.get_position() | ||
110 | (x_host, y_host) = host.get_position() | 110 | (x_host, y_host) = host.get_position() | ||
111 | return abs(x_kid - x_host) + abs(y_kid - y_host) | 111 | return abs(x_kid - x_host) + abs(y_kid - y_host) | ||
112 | 112 | ||||
113 | def get_nearest_nonvisited_host(self, kid, visited_hosts): | 113 | def get_nearest_nonvisited_host(self, kid, visited_hosts): | ||
114 | all_distances = dict() | 114 | all_distances = dict() | ||
115 | 115 | ||||
116 | for host in self._hosts: | 116 | for host in self._hosts: | ||
117 | if host not in visited_hosts: | 117 | if host not in visited_hosts: | ||
118 | current_distance = self.get_distance(kid, host) | 118 | current_distance = self.get_distance(kid, host) | ||
119 | all_distances[host] = current_distance | 119 | all_distances[host] = current_distance | ||
120 | if len(all_distances) != 0: | 120 | if len(all_distances) != 0: | ||
121 | sorted_distances_to_hosts = sorted(all_distances.items(), key = operator.itemgetter(1)) | 121 | sorted_distances_to_hosts = sorted(all_distances.items(), key = operator.itemgetter(1)) | ||
122 | min_distance = sorted_distances_to_hosts[0][1] | 122 | min_distance = sorted_distances_to_hosts[0][1] | ||
123 | nearest_hosts = [host for host, distance in sorted_distances_to_hosts if distance == min_distance] | 123 | nearest_hosts = [host for host, distance in sorted_distances_to_hosts if distance == min_distance] | ||
124 | if len(nearest_hosts) == 1: | 124 | if len(nearest_hosts) == 1: | ||
125 | return nearest_hosts[0] | 125 | return nearest_hosts[0] | ||
126 | else: | 126 | else: | ||
127 | sorted_hosts = sorted(nearest_hosts, key = lambda x: (x.get_position()[0], x.get_position()[1])) | 127 | sorted_hosts = sorted(nearest_hosts, key = lambda x: (x.get_position()[0], x.get_position()[1])) | ||
128 | return sorted_hosts[0] | 128 | return sorted_hosts[0] | ||
129 | return None | 129 | return None | ||
130 | 130 | ||||
131 | def set_kid_to_be_treated_by_host(self, kid, host): | 131 | def set_kid_to_be_treated_by_host(self, kid, host): | ||
132 | kid.visited_hosts.append(host) | 132 | kid.visited_hosts.append(host) | ||
133 | host.treated_kids.append(kid) | 133 | host.treated_kids.append(kid) | ||
134 | host.kids_to_be_treated.append(kid) | 134 | host.kids_to_be_treated.append(kid) | ||
135 | kid.set_position(host.get_position()) | 135 | kid.set_position(host.get_position()) | ||
136 | 136 | ||||
137 | def get_victim(self): | 137 | def get_victim(self): | ||
138 | self.split_participants() | 138 | self.split_participants() | ||
139 | kids_that_have_visited_everyone = set() | 139 | kids_that_have_visited_everyone = set() | ||
140 | hosts_that_have_treated_everyone = set() | 140 | hosts_that_have_treated_everyone = set() | ||
141 | 141 | ||||
142 | while(len(self.victims) == 0): | 142 | while(len(self.victims) == 0): | ||
143 | for kid in self._kids: | 143 | for kid in self._kids: | ||
144 | if len(kid.visited_hosts) == len(self._hosts): | 144 | if len(kid.visited_hosts) == len(self._hosts): | ||
145 | kids_that_have_visited_everyone.add(kid) | 145 | kids_that_have_visited_everyone.add(kid) | ||
146 | nearest_host = self.get_nearest_nonvisited_host(kid, kid.visited_hosts) | 146 | nearest_host = self.get_nearest_nonvisited_host(kid, kid.visited_hosts) | ||
147 | if nearest_host != None: | 147 | if nearest_host != None: | ||
148 | self.set_kid_to_be_treated_by_host(kid, nearest_host) | 148 | self.set_kid_to_be_treated_by_host(kid, nearest_host) | ||
149 | 149 | ||||
150 | for host in self._hosts: | 150 | for host in self._hosts: | ||
151 | if len(host.treated_kids) == len(self._kids): | 151 | if len(host.treated_kids) == len(self._kids): | ||
152 | hosts_that_have_treated_everyone.add(host) | 152 | hosts_that_have_treated_everyone.add(host) | ||
153 | ordered_kids = self.order_kids(host.kids_to_be_treated, host) | 153 | ordered_kids = self.order_kids(host.kids_to_be_treated, host) | ||
154 | 154 | ||||
155 | for kid in ordered_kids: | 155 | for kid in ordered_kids: | ||
156 | self.give_Candy(kid, host) | 156 | self.give_Candy(kid, host) | ||
157 | if kid.is_critical(): | 157 | if kid.is_critical(): | ||
158 | self.victims.add(kid) | 158 | self.victims.add(kid) | ||
159 | host.kids_to_be_treated = list() | 159 | host.kids_to_be_treated = list() | ||
160 | 160 | ||||
161 | if len(self.victims) != 0: | 161 | if len(self.victims) != 0: | ||
162 | break | 162 | break | ||
163 | if len(kids_that_have_visited_everyone) == len(self._kids) and len(hosts_that_have_treated_everyone) == len(self._hosts): | 163 | if len(kids_that_have_visited_everyone) == len(self._kids) and len(hosts_that_have_treated_everyone) == len(self._hosts): | ||
164 | break | 164 | break | ||
165 | 165 | ||||
166 | if len(self.victims) != 0: | 166 | if len(self.victims) != 0: | ||
167 | return self.victims | 167 | return self.victims | ||
168 | else: | 168 | else: | ||
169 | return None | 169 | return None | ||
t | 170 | t | |||
171 | candy = Candy(20, 0.3) | ||||
172 | person = Person((1, 2)) | ||||
173 | kid = Kid((0, 0), 123) | ||||
174 | host = Host((3, 4), [(1, 1.0), (2, 0.5)]) | ||||
175 | flux_capacitor = FluxCapacitor({kid, host}) | ||||
176 | print(flux_capacitor.get_victim()) |
Legends | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|