Домашни > Хелоуин в Припят > Решения > Решението на Велислава Крумова

Резултати
8 точки от тестове
0 точки от учител

8 точки общо

10 успешни теста
2 неуспешни теста
Код

  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, position):
 23        self.position = position
 24
 25
 26class Kid(Person):
 27
 28    def __init__(self, position, initiative):
 29        super().__init__(position)
 30        self.initiative = initiative
 31        self.candy_basket = []
 32        self.CONST_CRITICAL = 20
 33
 34    def get_initiative(self):
 35        return self.initiative
 36
 37    def add_candy(self, candy):
 38        self.candy_basket.append(candy)
 39
 40    def is_critical(self):
 41        return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > self.CONST_CRITICAL
 42
 43
 44class Host(Person):
 45
 46    def __init__(self, position, candies):
 47        super().__init__(position)
 48        self.candy_basket = [Candy(mass, uranium) for mass, uranium in candies]
 49
 50    def remove_candy(self, func):
 51        if not self.candy_basket:
 52            return None
 53        removed_candy = func(self.candy_basket)
 54        self.candy_basket.remove(removed_candy)
 55        return removed_candy
 56
 57
 58class FluxCapacitor:
 59    def __init__(self, participants):
 60        self.participants = participants
 61        self.all_hosts = [participant for participant in self.participants if isinstance(participant, Host)]
 62        self.all_kids = [participant for participant in self.participants if isinstance(participant, Kid)]
 63
 64    def get_victim(self):
 65        victims = set()
 66        visited_hosts = {kid: set() for kid in self.all_kids}
 67
 68        while True:
 69            new_victims = False
 70
 71            for kid in [k for k in self.all_kids if k not in victims]:
 72                closest_host = FluxCapacitor.find_closest_host(kid, visited_hosts[kid], self.all_hosts)
 73
 74                if closest_host is None:
 75                    continue
 76
 77                visited_hosts[kid].add(closest_host)
 78                kid.set_position(closest_host.get_position())
 79                candy = closest_host.remove_candy(FluxCapacitor.choose_candy_with_max_weight)
 80
 81                if candy is not None:
 82                    kid.add_candy(candy)
 83                    if kid.is_critical():
 84                        victims.add(kid)
 85                        new_victims = True
 86
 87            if new_victims or len(visited_hosts[kid]) == len(self.all_hosts):
 88                break
 89
 90        return victims if victims else None
 91
 92    @staticmethod
 93    def find_closest_host(kid, visited_hosts, hosts):
 94        closest_host = None
 95        closest_distance = float("inf")
 96        closest_info_tuple = (closest_distance, 0, 0)
 97
 98        for host in [h for h in hosts if h not in visited_hosts]:
 99            distance = FluxCapacitor.calculate_distance(kid.get_position(), host.get_position())
100            current_info_tuple = (distance, host.get_position()[0], host.get_position()[1])
101
102            if current_info_tuple < closest_info_tuple:
103                closest_host = host
104                closest_distance = distance
105                closest_info_tuple = (closest_distance, closest_host.get_position()[0], closest_host.get_position()[1])
106
107        return closest_host
108
109    @staticmethod
110    def calculate_distance(position1, position2):
111        return ((position1[0] - position2[0]) ** 2 + (position1[1] - position2[1]) ** 2) ** 0.5
112
113    @staticmethod
114    def choose_candy_with_max_weight(candies):
115        if not candies:
116            return None
117        return max(candies, key=lambda candy: candy.get_mass())

.E.E........
======================================================================
ERROR: 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 87, in get_victim
if new_victims or len(visited_hosts[kid]) == len(self.all_hosts):
UnboundLocalError: local variable 'kid' referenced before assignment

======================================================================
ERROR: 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 87, in get_victim
if new_victims or len(visited_hosts[kid]) == len(self.all_hosts):
UnboundLocalError: local variable 'kid' referenced before assignment

----------------------------------------------------------------------
Ran 12 tests in 0.001s

FAILED (errors=2)

Дискусия
История

f1class Candy:f1class Candy:
22
3    def __init__(self, mass, uranium):3    def __init__(self, mass, uranium):
4        self.mass = mass4        self.mass = mass
5        self.uranium = uranium5        self.uranium = uranium
66
7    def get_uranium_quantity(self):7    def get_uranium_quantity(self):
8        return self.mass * self.uranium8        return self.mass * self.uranium
99
10    def get_mass(self):10    def get_mass(self):
11        return self.mass11        return self.mass
1212
1313
14class Person:14class Person:
1515
16    def __init__(self, position):16    def __init__(self, position):
17        self.position = position17        self.position = position
1818
19    def get_position(self):19    def get_position(self):
20        return self.position20        return self.position
2121
22    def set_position(self, position):22    def set_position(self, position):
23        self.position = position23        self.position = position
2424
2525
26class Kid(Person):26class Kid(Person):
2727
28    def __init__(self, position, initiative):28    def __init__(self, position, initiative):
29        super().__init__(position)29        super().__init__(position)
30        self.initiative = initiative30        self.initiative = initiative
31        self.candy_basket = []31        self.candy_basket = []
nn32        self.CONST_CRITICAL = 20
3233
33    def get_initiative(self):34    def get_initiative(self):
34        return self.initiative35        return self.initiative
3536
36    def add_candy(self, candy):37    def add_candy(self, candy):
37        self.candy_basket.append(candy)38        self.candy_basket.append(candy)
3839
39    def is_critical(self):40    def is_critical(self):
n40        return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > 20n41        return sum(candy.get_uranium_quantity() for candy in self.candy_basket) > self.CONST_CRITICAL
4142
4243
43class Host(Person):44class Host(Person):
4445
45    def __init__(self, position, candies):46    def __init__(self, position, candies):
46        super().__init__(position)47        super().__init__(position)
47        self.candy_basket = [Candy(mass, uranium) for mass, uranium in candies]48        self.candy_basket = [Candy(mass, uranium) for mass, uranium in candies]
4849
49    def remove_candy(self, func):50    def remove_candy(self, func):
50        if not self.candy_basket:51        if not self.candy_basket:
51            return None52            return None
52        removed_candy = func(self.candy_basket)53        removed_candy = func(self.candy_basket)
53        self.candy_basket.remove(removed_candy)54        self.candy_basket.remove(removed_candy)
54        return removed_candy55        return removed_candy
5556
5657
57class FluxCapacitor:58class FluxCapacitor:
58    def __init__(self, participants):59    def __init__(self, participants):
59        self.participants = participants60        self.participants = participants
nn61        self.all_hosts = [participant for participant in self.participants if isinstance(participant, Host)]
62        self.all_kids = [participant for participant in self.participants if isinstance(participant, Kid)]
6063
61    def get_victim(self):64    def get_victim(self):
62        victims = set()65        victims = set()
n63        all_hosts = [participant for participant in self.participants if isinstance(participant, Host)]n
64        all_kids = [participant for participant in self.participants if isinstance(participant, Kid)]
65        visited_hosts = {kid: set() for kid in all_kids}66        visited_hosts = {kid: set() for kid in self.all_kids}
6667
67        while True:68        while True:
n68            no_new_victims = Truen69            new_victims = False
70 
69            for kid in [k for k in all_kids if k not in victims]:71            for kid in [k for k in self.all_kids if k not in victims]:
70                closest_host = FluxCapacitor.find_closest_host(kid, visited_hosts[kid], all_hosts)72                closest_host = FluxCapacitor.find_closest_host(kid, visited_hosts[kid], self.all_hosts)
7173
72                if closest_host is None:74                if closest_host is None:
73                    continue75                    continue
7476
75                visited_hosts[kid].add(closest_host)77                visited_hosts[kid].add(closest_host)
nn78                kid.set_position(closest_host.get_position())
76                candy = closest_host.remove_candy(FluxCapacitor.choose_candy_with_max_weight)79                candy = closest_host.remove_candy(FluxCapacitor.choose_candy_with_max_weight)
7780
78                if candy is not None:81                if candy is not None:
79                    kid.add_candy(candy)82                    kid.add_candy(candy)
n80                    visited_hosts[kid].add(closest_host)n
81                    if kid.is_critical():83                    if kid.is_critical():
82                        victims.add(kid)84                        victims.add(kid)
n83                        no_new_victims = Falsen85                        new_victims = True
8486
n85            if no_new_victims:n87            if new_victims or len(visited_hosts[kid]) == len(self.all_hosts):
86                break88                break
8789
88        return victims if victims else None90        return victims if victims else None
8991
90    @staticmethod92    @staticmethod
91    def find_closest_host(kid, visited_hosts, hosts):93    def find_closest_host(kid, visited_hosts, hosts):
92        closest_host = None94        closest_host = None
93        closest_distance = float("inf")95        closest_distance = float("inf")
nn96        closest_info_tuple = (closest_distance, 0, 0)
9497
95        for host in [h for h in hosts if h not in visited_hosts]:98        for host in [h for h in hosts if h not in visited_hosts]:
96            distance = FluxCapacitor.calculate_distance(kid.get_position(), host.get_position())99            distance = FluxCapacitor.calculate_distance(kid.get_position(), host.get_position())
n97            if distance < closest_distance or (distance == closest_distance and (host.get_position() < closest_host.get_position())):n100            current_info_tuple = (distance, host.get_position()[0], host.get_position()[1])
101 
102            if current_info_tuple < closest_info_tuple:
98                closest_host = host103                closest_host = host
99                closest_distance = distance104                closest_distance = distance
tt105                closest_info_tuple = (closest_distance, closest_host.get_position()[0], closest_host.get_position()[1])
100106
101        return closest_host107        return closest_host
102108
103    @staticmethod109    @staticmethod
104    def calculate_distance(position1, position2):110    def calculate_distance(position1, position2):
105        return ((position1[0] - position2[0]) ** 2 + (position1[1] - position2[1]) ** 2) ** 0.5111        return ((position1[0] - position2[0]) ** 2 + (position1[1] - position2[1]) ** 2) ** 0.5
106112
107    @staticmethod113    @staticmethod
108    def choose_candy_with_max_weight(candies):114    def choose_candy_with_max_weight(candies):
109        if not candies:115        if not candies:
110            return None116            return None
111        return max(candies, key=lambda candy: candy.get_mass())117        return max(candies, key=lambda candy: candy.get_mass())
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op