1class Candy:
2
3 def __init__(self, mass, uranium):
4 self.mass = mass
5 self.uranium = uranium
6
7 def get_uranium_quantity(self):
8 return self.mass * self.uranium
9
10 def get_mass(self):
11 return self.mass
12
13
14class Person:
15
16 def __init__(self, position):
17 self.position = position
18
19 def get_position(self):
20 return self.position
21
22 def set_position(self, new_position):
23 self.position = new_position
24
25
26class Kid(Person):
27
28 CRITICAL_MASS = 20
29
30 def __init__(self, position, initiative):
31 super().__init__(position)
32 self.initiative = initiative
33 self.not_visited = set()
34 self.basket = set()
35
36 def get_initiative(self):
37 return self.initiative
38
39 def add_candy(self, candy):
40 self.basket.add(candy)
41
42 def is_critical(self):
43 uranium_in_basket = 0
44 for candy in self.basket:
45 uranium_in_basket += candy.get_uranium_quantity()
46 return uranium_in_basket > self.CRITICAL_MASS
47
48 def set_not_visited_hosts(self, hosts):
49 self.not_visited = {host for host in hosts}
50
51 def closest_host(self, hosts): #остава си така :/
52 distances_by_X = {host : abs(self.position[0] - host.position[0]) for host in hosts}
53 closest_by_X = {key : value for key, value in distances_by_X.items() if value == min(distances_by_X.values())}
54 distances = {host : abs(self.position[1] - host.position[1]) for host in closest_by_X}
55 closest_host = [key for key, value in distances.items() if value == min(distances.values())]
56 return closest_host[0]
57
58
59class Host(Person):
60
61 def __init__(self, position, candies):
62 super().__init__(position)
63 self.candies = candies
64 self.visited_by = set()
65
66 def remove_candy(self, func):
67 if len(self.candies) == 0:
68 return
69 return func
70
71 def set_visited_by(self, kids):
72 self.visited_by = {kid for kid in kids if self.position == kid.position}
73
74
75class FluxCapacitor:
76
77 def __init__(self, participants):
78 self.participants = participants
79 self.hosts = {person for person in self.participants if type(person) is Host}
80 self.kids = {person for person in self.participants if type(person) is Kid}
81
82 @staticmethod
83 def which_candy(candies):
84 this_candy = max(candies, key=lambda candy: candy.mass)
85 candies.remove(this_candy)
86 return this_candy
87
88 def get_victim(self):
89 victims = set()
90
91 for kid in self.kids: #създавам списък с непосетени домакини за всяко дете
92 kid.set_not_visited_hosts(self.hosts)
93
94 for _ in range(len(self.hosts)):
95 for kid in self.kids: #всяко дете се мести до най-близкия си домакин и го "отметва" като посетен
96 closest_host = kid.closest_host(kid.not_visited)
97 kid.set_position(closest_host.position)
98 kid.not_visited.remove(closest_host)
99
100 for host in self.hosts: #раздаване на бонбони
101 if len(host.candies) == 0: #ако домакинът няма бонбони, го "подминаваме"
102 continue
103
104 remove = host.remove_candy(self.which_candy)
105 host.set_visited_by(self.kids) #сортирам децата, посетили даден домакин, низходящо по инициатива
106 sorted_initiative = sorted(host.visited_by, key=lambda kid : kid.initiative, reverse=True)
107
108 for kid in sorted_initiative:
109 kid.add_candy(remove(host.candies)) #даваме бонбон
110 if kid.is_critical(): #проверявам дали детето е радиоактивно
111 victims.add(kid)
112
113 if len(victims) != 0: #първата инстанция, в която victims не е празен, спираме играта
114 return victims
115
116 return
.....EE.....
======================================================================
ERROR: 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})
File "/tmp/solution.py", line 109, in get_victim
kid.add_candy(remove(host.candies)) #даваме бонбон
File "/tmp/solution.py", line 84, in which_candy
this_candy = max(candies, key=lambda candy: candy.mass)
File "/tmp/solution.py", line 84, in <lambda>
this_candy = max(candies, key=lambda candy: candy.mass)
AttributeError: 'tuple' object has no attribute 'mass'
======================================================================
ERROR: test_basic_usage (test.HostTest)
Test basic usage of Host class.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/tmp/test.py", line 66, in test_basic_usage
self.assertEqual(candy.get_mass(), 456)
AttributeError: 'function' object has no attribute 'get_mass'
----------------------------------------------------------------------
Ran 12 tests in 0.001s
FAILED (errors=2)
Константин Кирязов
04.11.2023 21:28Ясно ми е. Ще продължа да мисля по задачата. <br> Не пращам недовършено домашно с цел да се откажа от него, а просто да кача нещо повече от нищо в случай, че наистина не успея с него.
|
Георги Кунчев
04.11.2023 20:40Пораженчески подход е това. Приемам го за валидно становище и няма да натискам за повече, но така не мисля, че ще прогресираш. Опитай поне. Нищо не губиш.
|
Константин Кирязов
04.11.2023 20:33Качвам класовете без FluxCapacitor. Доста тежко съм се запънал с това домашно и реших да изчакам да видя решенията на колегите ми и да се науча от тях, вместо да се тормозя повече
|
| f | 1 | class Candy: | f | 1 | class Candy: |
| 2 | 2 | ||||
| 3 | def __init__(self, mass, uranium): | 3 | def __init__(self, mass, uranium): | ||
| 4 | self.mass = mass | 4 | self.mass = mass | ||
| 5 | self.uranium = uranium | 5 | self.uranium = uranium | ||
| 6 | 6 | ||||
| 7 | def get_uranium_quantity(self): | 7 | def get_uranium_quantity(self): | ||
| 8 | return self.mass * self.uranium | 8 | return self.mass * self.uranium | ||
| 9 | 9 | ||||
| 10 | def get_mass(self): | 10 | def get_mass(self): | ||
| 11 | return self.mass | 11 | return self.mass | ||
| 12 | 12 | ||||
| 13 | 13 | ||||
| 14 | class Person: | 14 | class Person: | ||
| 15 | 15 | ||||
| 16 | def __init__(self, position): | 16 | def __init__(self, position): | ||
| 17 | self.position = position | 17 | self.position = position | ||
| 18 | 18 | ||||
| 19 | def get_position(self): | 19 | def get_position(self): | ||
| 20 | return self.position | 20 | return self.position | ||
| 21 | 21 | ||||
| 22 | def set_position(self, new_position): | 22 | def set_position(self, new_position): | ||
| 23 | self.position = new_position | 23 | self.position = new_position | ||
| 24 | 24 | ||||
| 25 | 25 | ||||
| 26 | class Kid(Person): | 26 | class Kid(Person): | ||
| 27 | 27 | ||||
| 28 | CRITICAL_MASS = 20 | 28 | CRITICAL_MASS = 20 | ||
| 29 | 29 | ||||
| 30 | def __init__(self, position, initiative): | 30 | def __init__(self, position, initiative): | ||
| 31 | super().__init__(position) | 31 | super().__init__(position) | ||
| 32 | self.initiative = initiative | 32 | self.initiative = initiative | ||
| 33 | self.not_visited = set() | 33 | self.not_visited = set() | ||
| 34 | self.basket = set() | 34 | self.basket = set() | ||
| 35 | 35 | ||||
| 36 | def get_initiative(self): | 36 | def get_initiative(self): | ||
| 37 | return self.initiative | 37 | return self.initiative | ||
| 38 | 38 | ||||
| 39 | def add_candy(self, candy): | 39 | def add_candy(self, candy): | ||
| 40 | self.basket.add(candy) | 40 | self.basket.add(candy) | ||
| 41 | 41 | ||||
| 42 | def is_critical(self): | 42 | def is_critical(self): | ||
| 43 | uranium_in_basket = 0 | 43 | uranium_in_basket = 0 | ||
| 44 | for candy in self.basket: | 44 | for candy in self.basket: | ||
| 45 | uranium_in_basket += candy.get_uranium_quantity() | 45 | uranium_in_basket += candy.get_uranium_quantity() | ||
| 46 | return uranium_in_basket > self.CRITICAL_MASS | 46 | return uranium_in_basket > self.CRITICAL_MASS | ||
| 47 | 47 | ||||
| 48 | def set_not_visited_hosts(self, hosts): | 48 | def set_not_visited_hosts(self, hosts): | ||
| 49 | self.not_visited = {host for host in hosts} | 49 | self.not_visited = {host for host in hosts} | ||
| 50 | 50 | ||||
| n | 51 | def closest_host(self, hosts): #отвратително нечетимo, но поне работи :smile: | n | 51 | def closest_host(self, hosts): #остава си така :/ |
| 52 | distances_by_X = {host : abs(kid.position[0] - host.position[0]) for host in hosts} | 52 | distances_by_X = {host : abs(self.position[0] - host.position[0]) for host in hosts} | ||
| 53 | closest_distance_by_X = min(distances_by_X.values()) | ||||
| 54 | closest_by_X = {key : value for key, value in distances_by_X.items() if value == closest_distance_by_X} | 53 | closest_by_X = {key : value for key, value in distances_by_X.items() if value == min(distances_by_X.values())} | ||
| 55 | distances = {host : abs(kid.position[1] - host.position[1]) for host in closest_by_X} | 54 | distances = {host : abs(self.position[1] - host.position[1]) for host in closest_by_X} | ||
| 56 | closest_distance = min(distances.values()) | ||||
| 57 | closest_host = [key for key, value in distances.items() if value == closest_distance] | 55 | closest_host = [key for key, value in distances.items() if value == min(distances.values())] | ||
| 58 | return closest_host[0] | 56 | return closest_host[0] | ||
| 59 | 57 | ||||
| 60 | 58 | ||||
| 61 | class Host(Person): | 59 | class Host(Person): | ||
| 62 | 60 | ||||
| n | 63 | count = 0 | n | ||
| 64 | |||||
| 65 | def __init__(self, position, candies): | 61 | def __init__(self, position, candies): | ||
| 66 | super().__init__(position) | 62 | super().__init__(position) | ||
| 67 | self.candies = candies | 63 | self.candies = candies | ||
| n | 68 | self.count += 1 | n | ||
| 69 | self.visited_by = set() | 64 | self.visited_by = set() | ||
| 70 | 65 | ||||
| 71 | def remove_candy(self, func): | 66 | def remove_candy(self, func): | ||
| n | 72 | if self.candies == []: | n | 67 | if len(self.candies) == 0: |
| 73 | return None | 68 | return | ||
| 74 | return func | 69 | return func | ||
| 75 | 70 | ||||
| 76 | def set_visited_by(self, kids): | 71 | def set_visited_by(self, kids): | ||
| 77 | self.visited_by = {kid for kid in kids if self.position == kid.position} | 72 | self.visited_by = {kid for kid in kids if self.position == kid.position} | ||
| 78 | 73 | ||||
| 79 | 74 | ||||
| 80 | class FluxCapacitor: | 75 | class FluxCapacitor: | ||
| 81 | 76 | ||||
| 82 | def __init__(self, participants): | 77 | def __init__(self, participants): | ||
| 83 | self.participants = participants | 78 | self.participants = participants | ||
| n | n | 79 | self.hosts = {person for person in self.participants if type(person) is Host} | ||
| 80 | self.kids = {person for person in self.participants if type(person) is Kid} | ||||
| 81 | |||||
| 82 | @staticmethod | ||||
| 83 | def which_candy(candies): | ||||
| 84 | this_candy = max(candies, key=lambda candy: candy.mass) | ||||
| 85 | candies.remove(this_candy) | ||||
| 86 | return this_candy | ||||
| 84 | 87 | ||||
| 85 | def get_victim(self): | 88 | def get_victim(self): | ||
| 86 | victims = set() | 89 | victims = set() | ||
| n | 87 | Kids = set() | n | ||
| 88 | Hosts = set() | ||||
| 89 | |||||
| 90 | def which_candy(candies): #предварително си дефинирам функцията за remove_candy | ||||
| 91 | max_mass = max([candy.mass for candy in candies]) | ||||
| 92 | this_candy = candies[0] | ||||
| 93 | for candy in candies: | ||||
| 94 | if candy.mass == max_mass: | ||||
| 95 | this_candy = candy | ||||
| 96 | candies.remove(this_candy) | ||||
| 97 | return this_candy | ||||
| 98 | |||||
| 99 | for person in self.participants: #разделям участниците на Деца и Домакини | ||||
| 100 | if type(person) is Kid: | ||||
| 101 | Kids.add(person) | ||||
| 102 | else: | ||||
| 103 | Hosts.add(person) | ||||
| 104 | 90 | ||||
| n | 105 | for kid in Kids: #създавам списък с непосетени домакини за всяко дете | n | 91 | for kid in self.kids: #създавам списък с непосетени домакини за всяко дете |
| 106 | kid.set_not_visited_hosts(Hosts) | 92 | kid.set_not_visited_hosts(self.hosts) | ||
| 107 | 93 | ||||
| n | 108 | for _ in range(Host.count): | n | 94 | for _ in range(len(self.hosts)): |
| 109 | for kid in Kids: #всяко дете се мести до най-близкия си домакин и го "отметва" като посетен | 95 | for kid in self.kids: #всяко дете се мести до най-близкия си домакин и го "отметва" като посетен | ||
| 110 | closest_host = kid.closest_host(kid.not_visited) | 96 | closest_host = kid.closest_host(kid.not_visited) | ||
| 111 | kid.set_position(closest_host.position) | 97 | kid.set_position(closest_host.position) | ||
| t | 112 | kid.not_visited.remove(closest_host) | t | 98 | kid.not_visited.remove(closest_host) |
| 113 | for host in Hosts: | 99 | |||
| 100 | for host in self.hosts: #раздаване на бонбони | ||||
| 101 | if len(host.candies) == 0: #ако домакинът няма бонбони, го "подминаваме" | ||||
| 102 | continue | ||||
| 103 | |||||
| 114 | remove = host.remove_candy(which_candy) | 104 | remove = host.remove_candy(self.which_candy) | ||
| 115 | host.set_visited_by(Kids) | 105 | host.set_visited_by(self.kids) #сортирам децата, посетили даден домакин, низходящо по инициатива | ||
| 116 | host.visited_by.sort(key = lambda kid : kid.initiative, reverse = True) | 106 | sorted_initiative = sorted(host.visited_by, key=lambda kid : kid.initiative, reverse=True) | ||
| 107 | |||||
| 117 | for kid in host.visited_by: | 108 | for kid in sorted_initiative: | ||
| 118 | kid.add_candy(remove(host.candies)) | 109 | kid.add_candy(remove(host.candies)) #даваме бонбон | ||
| 119 | if kid.is_critical(): | 110 | if kid.is_critical(): #проверявам дали детето е радиоактивно | ||
| 120 | victims.add(kid) | 111 | victims.add(kid) | ||
| 112 | |||||
| 113 | if len(victims) != 0: #първата инстанция, в която victims не е празен, спираме играта | ||||
| 121 | return victims | 114 | return victims | ||
| 115 | |||||
| 122 | return None | 116 | return |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | class Candy: | f | 1 | class Candy: |
| 2 | 2 | ||||
| 3 | def __init__(self, mass, uranium): | 3 | def __init__(self, mass, uranium): | ||
| 4 | self.mass = mass | 4 | self.mass = mass | ||
| 5 | self.uranium = uranium | 5 | self.uranium = uranium | ||
| 6 | 6 | ||||
| 7 | def get_uranium_quantity(self): | 7 | def get_uranium_quantity(self): | ||
| n | 8 | return self.mass*self.uranium | n | 8 | return self.mass * self.uranium |
| 9 | 9 | ||||
| 10 | def get_mass(self): | 10 | def get_mass(self): | ||
| 11 | return self.mass | 11 | return self.mass | ||
| 12 | 12 | ||||
| 13 | 13 | ||||
| 14 | class Person: | 14 | class Person: | ||
| 15 | 15 | ||||
| 16 | def __init__(self, position): | 16 | def __init__(self, position): | ||
| 17 | self.position = position | 17 | self.position = position | ||
| 18 | 18 | ||||
| 19 | def get_position(self): | 19 | def get_position(self): | ||
| 20 | return self.position | 20 | return self.position | ||
| 21 | 21 | ||||
| 22 | def set_position(self, new_position): | 22 | def set_position(self, new_position): | ||
| 23 | self.position = new_position | 23 | self.position = new_position | ||
| 24 | 24 | ||||
| 25 | 25 | ||||
| 26 | class Kid(Person): | 26 | class Kid(Person): | ||
| 27 | 27 | ||||
| n | n | 28 | CRITICAL_MASS = 20 | ||
| 29 | |||||
| 28 | def __init__(self, position, initiative): | 30 | def __init__(self, position, initiative): | ||
| 29 | super().__init__(position) | 31 | super().__init__(position) | ||
| 30 | self.initiative = initiative | 32 | self.initiative = initiative | ||
| n | n | 33 | self.not_visited = set() | ||
| 31 | self.basket = [] | 34 | self.basket = set() | ||
| 32 | 35 | ||||
| 33 | def get_initiative(self): | 36 | def get_initiative(self): | ||
| 34 | return self.initiative | 37 | return self.initiative | ||
| 35 | 38 | ||||
| 36 | def add_candy(self, candy): | 39 | def add_candy(self, candy): | ||
| n | 37 | self.basket.append(candy) | n | 40 | self.basket.add(candy) |
| 38 | 41 | ||||
| 39 | def is_critical(self): | 42 | def is_critical(self): | ||
| 40 | uranium_in_basket = 0 | 43 | uranium_in_basket = 0 | ||
| 41 | for candy in self.basket: | 44 | for candy in self.basket: | ||
| 42 | uranium_in_basket += candy.get_uranium_quantity() | 45 | uranium_in_basket += candy.get_uranium_quantity() | ||
| n | 43 | return uranium_in_basket > 20 | n | 46 | return uranium_in_basket > self.CRITICAL_MASS |
| 44 | 47 | ||||
| n | n | 48 | def set_not_visited_hosts(self, hosts): | ||
| 49 | self.not_visited = {host for host in hosts} | ||||
| 50 | |||||
| 51 | def closest_host(self, hosts): #отвратително нечетимo, но поне работи :smile: | ||||
| 52 | distances_by_X = {host : abs(kid.position[0] - host.position[0]) for host in hosts} | ||||
| 53 | closest_distance_by_X = min(distances_by_X.values()) | ||||
| 54 | closest_by_X = {key : value for key, value in distances_by_X.items() if value == closest_distance_by_X} | ||||
| 55 | distances = {host : abs(kid.position[1] - host.position[1]) for host in closest_by_X} | ||||
| 56 | closest_distance = min(distances.values()) | ||||
| 57 | closest_host = [key for key, value in distances.items() if value == closest_distance] | ||||
| 58 | return closest_host[0] | ||||
| 59 | |||||
| 45 | 60 | ||||
| 46 | class Host(Person): | 61 | class Host(Person): | ||
| n | n | 62 | |||
| 63 | count = 0 | ||||
| 47 | 64 | ||||
| 48 | def __init__(self, position, candies): | 65 | def __init__(self, position, candies): | ||
| 49 | super().__init__(position) | 66 | super().__init__(position) | ||
| 50 | self.candies = candies | 67 | self.candies = candies | ||
| n | n | 68 | self.count += 1 | ||
| 69 | self.visited_by = set() | ||||
| 51 | 70 | ||||
| 52 | def remove_candy(self, func): | 71 | def remove_candy(self, func): | ||
| 53 | if self.candies == []: | 72 | if self.candies == []: | ||
| 54 | return None | 73 | return None | ||
| 55 | return func | 74 | return func | ||
| n | n | 75 | |||
| 76 | def set_visited_by(self, kids): | ||||
| 77 | self.visited_by = {kid for kid in kids if self.position == kid.position} | ||||
| 56 | 78 | ||||
| 57 | 79 | ||||
| 58 | class FluxCapacitor: | 80 | class FluxCapacitor: | ||
| 59 | 81 | ||||
| 60 | def __init__(self, participants): | 82 | def __init__(self, participants): | ||
| 61 | self.participants = participants | 83 | self.participants = participants | ||
| 62 | 84 | ||||
| t | 63 | #def get_victim(self): | t | 85 | def get_victim(self): |
| 86 | victims = set() | ||||
| 87 | Kids = set() | ||||
| 88 | Hosts = set() | ||||
| 89 | |||||
| 90 | def which_candy(candies): #предварително си дефинирам функцията за remove_candy | ||||
| 91 | max_mass = max([candy.mass for candy in candies]) | ||||
| 92 | this_candy = candies[0] | ||||
| 93 | for candy in candies: | ||||
| 94 | if candy.mass == max_mass: | ||||
| 95 | this_candy = candy | ||||
| 96 | candies.remove(this_candy) | ||||
| 97 | return this_candy | ||||
| 98 | |||||
| 99 | for person in self.participants: #разделям участниците на Деца и Домакини | ||||
| 100 | if type(person) is Kid: | ||||
| 101 | Kids.add(person) | ||||
| 102 | else: | ||||
| 103 | Hosts.add(person) | ||||
| 104 | |||||
| 105 | for kid in Kids: #създавам списък с непосетени домакини за всяко дете | ||||
| 106 | kid.set_not_visited_hosts(Hosts) | ||||
| 107 | |||||
| 108 | for _ in range(Host.count): | ||||
| 109 | for kid in Kids: #всяко дете се мести до най-близкия си домакин и го "отметва" като посетен | ||||
| 110 | closest_host = kid.closest_host(kid.not_visited) | ||||
| 111 | kid.set_position(closest_host.position) | ||||
| 112 | kid.not_visited.remove(closest_host) | ||||
| 113 | for host in Hosts: | ||||
| 114 | remove = host.remove_candy(which_candy) | ||||
| 115 | host.set_visited_by(Kids) | ||||
| 116 | host.visited_by.sort(key = lambda kid : kid.initiative, reverse = True) | ||||
| 117 | for kid in host.visited_by: | ||||
| 118 | kid.add_candy(remove(host.candies)) | ||||
| 119 | if kid.is_critical(): | ||||
| 120 | victims.add(kid) | ||||
| 121 | return victims | ||||
| 64 | #return | 122 | return None |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||