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

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

9 точки общо

11 успешни теста
1 неуспешни теста
Код

  1class Candy:
  2    def __init__(self, mass, uranium):
  3        self.mass = mass
  4        self.uranium = uranium
  5
  6    def get_uranium_quantity(self):
  7        return self.mass * self.uranium
  8
  9    def get_mass(self):
 10        return self.mass
 11
 12
 13class Person:
 14    def __init__(self, position):
 15        self.position = position
 16
 17    def get_position(self):
 18        return self.position
 19
 20    def set_position(self, new_position):
 21        self.position = new_position
 22
 23
 24class Kid(Person):
 25    THRESHOLD_URANIUM = 20
 26
 27    def __init__(self, position, initiative):
 28        super().__init__(position)
 29        self.initiative = initiative
 30        self.candy_basket = []
 31        self.visited_hosts = set()
 32
 33    def get_initiative(self):
 34        return self.initiative
 35
 36    def add_candy(self, candy):
 37        self.candy_basket.append(candy)
 38
 39    def add_host(self, host):
 40        self.visited_hosts.add(host)
 41
 42    def is_critical(self):
 43        total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket)
 44        return total_uranium > self.THRESHOLD_URANIUM
 45
 46
 47class Host(Person):
 48    def __init__(self, position, candies):
 49        super().__init__(position)
 50        self.candy_basket = [Candy(*candy) for candy in candies]
 51
 52    def remove_candy(self, selection_function):
 53        if self.candy_basket:
 54            selected_candy = selection_function(self.candy_basket)
 55            self.candy_basket.remove(selected_candy)
 56            return selected_candy
 57        else:
 58            return None
 59
 60
 61def find_closest_host(kid, hosts):
 62    closest_host = None
 63    min_distance = float('inf')
 64
 65    for host in hosts:
 66        if host not in kid.visited_hosts and host.candy_basket:
 67            distance = abs(host.get_position()[0] - kid.get_position()[0]) + abs(host.get_position()[1] - kid.get_position()[1])
 68            if distance < min_distance:
 69                min_distance = distance
 70                closest_host = host
 71            elif distance == min_distance:
 72                if host.get_position()[0] < closest_host.get_position()[0]:
 73                    closest_host = host
 74                elif host.get_position()[0] == closest_host.get_position()[0] and host.get_position()[1] < closest_host.get_position()[1]:
 75                    closest_host = host
 76
 77    return closest_host
 78
 79
 80class FluxCapacitor:
 81    
 82    def __init__(self, participants):
 83        self.participants = participants
 84        self.kids = [participant for participant in participants if isinstance(participant, Kid)]
 85        self.hosts = [participant for participant in participants if isinstance(participant, Host)]
 86
 87    @staticmethod
 88    def select_max_mass_candy(candies):
 89        return max(candies, key=lambda candy: candy.get_mass())
 90
 91    def get_victim(self):
 92
 93        victims = set()
 94
 95        while True:
 96            
 97            if all(len(kid.visited_hosts) == len(self.hosts) for kid in self.kids):
 98                return None
 99
100            for kid in self.kids:
101                closest_host = find_closest_host(kid, self.hosts)
102
103                if closest_host:
104                    candy = closest_host.remove_candy(self.select_max_mass_candy)
105                    if candy:
106                        kid.add_candy(candy)
107                        kid.add_host(closest_host)
108                        kid.set_position(closest_host.get_position())
109
110                    if kid.is_critical():
111                        victims.add(kid)
112
113            if not victims:
114                continue
115            else:
116                return victims
117                

....F.......
======================================================================
FAIL: test_no_candies (test.FluxCapacitorTest)
Test with no candies.
----------------------------------------------------------------------
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 106, in test_no_candies
self.assertEqual(flux_capacitor.get_victim(), None)
File "/tmp/solution.py", line 101, in get_victim
closest_host = find_closest_host(kid, self.hosts)
File "/tmp/solution.py", line 61, in find_closest_host
def find_closest_host(kid, hosts):
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'

----------------------------------------------------------------------
Ran 12 tests in 0.201s

FAILED (failures=1)

Дискусия
Георги Кунчев
07.11.2023 11:25

Поради проблемите, свързани с безкрайни цикли в някои от тестовете, добавихме подобрение на сайта, така че той вече ще отрази точките на всички останали тестове. Ако имаш безкраен цикъл за някой тест кейс, той ще касае само него и все пак ще получиш точки за остнаалите си тестове.
Габриела Костева
07.11.2023 10:44

Изтествах и случая, в който трябва да върне None и също нямам безкраен цикъл
Георги Кунчев
07.11.2023 10:26

Ако ти дам, ще е нечестно спрямо останалите :(. Виж граничните стойности
Габриела Костева
07.11.2023 10:23

Аз пробвах този случай: k1 = Kid((1, 1), 1) k2 = Kid((-8, 2), -5) k4 = Kid((14, -7), 12) k5 = Kid((5, 9), 2) h1 = Host((0, 0), [(5.2, 0.2), (1.2, 0.1111), (4.3333, 0.78592), (2.1, 0.3), (3.2, 0.4), (5.2, 0.2), (1.2, 0.1111), (4.3333, 0.78592), (2.1, 0.3), (3.2, 0.4)]) h2 = Host((21, 5), [(12.4, 0.5), (8.3, 0.999), (3.257849, 0.12345), (1.2, 0.2), (2.1, 0.3), (3.2, 0.4), (12.4, 0.5), (8.3, 0.999), (3.257849, 0.12345)]) h3 = Host((-13, 2), [(11, 0.2), (4.43432, 0.7), (9.123, 1), (1.2, 1), (2.1, 1), (3.2, 0.99), (3.2, 1), (3.2, 1), (3.2, 1), (3.2, 1), ]) h4 = Host((0, 0), [(5.2, 0.2), (1.2, 0.1111), (4.3333, 0.78592), (2.1, 0.3), (3.2, 0.4), (5.2, 0.2), (1.2, 0.1111), (4.3333, 0.78592), (2.1, 0.3), (3.2, 0.4)]) h5 = Host((21, 5), [(12.4, 0.5), (8.3, 0.999), (3.257849, 0.12345), (1.2, 0.2), (2.1, 0.3), (3.2, 0.4), (12.4, 0.5), (8.3, 0.999), (3.257849, 0.12345)]) h6 = Host((-13, 2), [(11, 0.2), (4.43432, 0.7), (9.123, 1), (1.2, 1), (2.1, 1), (3.2, 0.99), (3.2, 1), (3.2, 1), (3.2, 1), (3.2, 1), ]) people = {k1, h3, h2, k5, h4, h5, h6, h1, k4, k2} fc = FluxCapacitor(people) while (output := fc.get_victim()) is not None: print(output); и ми изкарва този резултат: {<__main__.Kid object at 0x7faf0e714e90>, <__main__.Kid object at 0x7faf0e714d10>, <__main__.Kid object at 0x7faf0e714050>} {<__main__.Kid object at 0x7faf0e714e90>, <__main__.Kid object at 0x7faf0e714d10>, <__main__.Kid object at 0x7faf0e714050>} {<__main__.Kid object at 0x7faf0e714050>}, но безкраен цикъл не съм удряла. Може ли да ми дадеш един примерен вход, в който се случва това
Георги Кунчев
07.11.2023 08:57

Имаш безкраен цикъл, заради който тестовете ни ще зависнат и няма д аполучиш точки. Моля изтествай с реален случай. Преди последната промяна беше добре.
История

f1class Candy:f1class Candy:
2    def __init__(self, mass, uranium):2    def __init__(self, mass, uranium):
3        self.mass = mass3        self.mass = mass
4        self.uranium = uranium4        self.uranium = uranium
55
6    def get_uranium_quantity(self):6    def get_uranium_quantity(self):
7        return self.mass * self.uranium7        return self.mass * self.uranium
88
9    def get_mass(self):9    def get_mass(self):
10        return self.mass10        return self.mass
1111
1212
13class Person:13class Person:
14    def __init__(self, position):14    def __init__(self, position):
15        self.position = position15        self.position = position
1616
17    def get_position(self):17    def get_position(self):
18        return self.position18        return self.position
1919
20    def set_position(self, new_position):20    def set_position(self, new_position):
21        self.position = new_position21        self.position = new_position
2222
2323
24class Kid(Person):24class Kid(Person):
25    THRESHOLD_URANIUM = 2025    THRESHOLD_URANIUM = 20
2626
27    def __init__(self, position, initiative):27    def __init__(self, position, initiative):
28        super().__init__(position)28        super().__init__(position)
29        self.initiative = initiative29        self.initiative = initiative
30        self.candy_basket = []30        self.candy_basket = []
31        self.visited_hosts = set()31        self.visited_hosts = set()
3232
33    def get_initiative(self):33    def get_initiative(self):
34        return self.initiative34        return self.initiative
3535
36    def add_candy(self, candy):36    def add_candy(self, candy):
37        self.candy_basket.append(candy)37        self.candy_basket.append(candy)
3838
39    def add_host(self, host):39    def add_host(self, host):
40        self.visited_hosts.add(host)40        self.visited_hosts.add(host)
4141
42    def is_critical(self):42    def is_critical(self):
43        total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket)43        total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket)
44        return total_uranium > self.THRESHOLD_URANIUM44        return total_uranium > self.THRESHOLD_URANIUM
4545
4646
47class Host(Person):47class Host(Person):
48    def __init__(self, position, candies):48    def __init__(self, position, candies):
49        super().__init__(position)49        super().__init__(position)
50        self.candy_basket = [Candy(*candy) for candy in candies]50        self.candy_basket = [Candy(*candy) for candy in candies]
5151
52    def remove_candy(self, selection_function):52    def remove_candy(self, selection_function):
53        if self.candy_basket:53        if self.candy_basket:
54            selected_candy = selection_function(self.candy_basket)54            selected_candy = selection_function(self.candy_basket)
55            self.candy_basket.remove(selected_candy)55            self.candy_basket.remove(selected_candy)
56            return selected_candy56            return selected_candy
57        else:57        else:
58            return None58            return None
5959
6060
61def find_closest_host(kid, hosts):61def find_closest_host(kid, hosts):
62    closest_host = None62    closest_host = None
63    min_distance = float('inf')63    min_distance = float('inf')
6464
65    for host in hosts:65    for host in hosts:
n66        if host not in kid.visited_hosts:n66        if host not in kid.visited_hosts and host.candy_basket:
67            distance = abs(host.get_position()[0] - kid.get_position()[0]) + abs(host.get_position()[1] - kid.get_position()[1])67            distance = abs(host.get_position()[0] - kid.get_position()[0]) + abs(host.get_position()[1] - kid.get_position()[1])
68            if distance < min_distance:68            if distance < min_distance:
69                min_distance = distance69                min_distance = distance
70                closest_host = host70                closest_host = host
71            elif distance == min_distance:71            elif distance == min_distance:
72                if host.get_position()[0] < closest_host.get_position()[0]:72                if host.get_position()[0] < closest_host.get_position()[0]:
73                    closest_host = host73                    closest_host = host
74                elif host.get_position()[0] == closest_host.get_position()[0] and host.get_position()[1] < closest_host.get_position()[1]:74                elif host.get_position()[0] == closest_host.get_position()[0] and host.get_position()[1] < closest_host.get_position()[1]:
75                    closest_host = host75                    closest_host = host
7676
77    return closest_host77    return closest_host
7878
7979
80class FluxCapacitor:80class FluxCapacitor:
nn81    
81    def __init__(self, participants):82    def __init__(self, participants):
82        self.participants = participants83        self.participants = participants
83        self.kids = [participant for participant in participants if isinstance(participant, Kid)]84        self.kids = [participant for participant in participants if isinstance(participant, Kid)]
84        self.hosts = [participant for participant in participants if isinstance(participant, Host)]85        self.hosts = [participant for participant in participants if isinstance(participant, Host)]
8586
86    @staticmethod87    @staticmethod
87    def select_max_mass_candy(candies):88    def select_max_mass_candy(candies):
88        return max(candies, key=lambda candy: candy.get_mass())89        return max(candies, key=lambda candy: candy.get_mass())
8990
90    def get_victim(self):91    def get_victim(self):
9192
92        victims = set()93        victims = set()
9394
94        while True:95        while True:
nn96            
97            if all(len(kid.visited_hosts) == len(self.hosts) for kid in self.kids):
98                return None
9599
96            for kid in self.kids:100            for kid in self.kids:
n97                while len(kid.visited_hosts) is not len(self.hosts):n
98                    closest_host = find_closest_host(kid, self.hosts)101                closest_host = find_closest_host(kid, self.hosts)
99102
n100                    if closest_host:n103                if closest_host:
101                        candy = closest_host.remove_candy(self.select_max_mass_candy)104                    candy = closest_host.remove_candy(self.select_max_mass_candy)
102                        if candy:105                    if candy:
103                            kid.add_candy(candy)106                        kid.add_candy(candy)
104                            kid.add_host(closest_host)107                        kid.add_host(closest_host)
105                            kid.set_position(closest_host.get_position())108                        kid.set_position(closest_host.get_position())
106109
107                    if kid.is_critical():110                    if kid.is_critical():
108                        victims.add(kid)111                        victims.add(kid)
n109                        breakn
110112
111            if not victims:113            if not victims:
n112                return Nonen114                continue
113            else:115            else:
114                return victims116                return victims
tt117                
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op

f1class Candy:f1class Candy:
2    def __init__(self, mass, uranium):2    def __init__(self, mass, uranium):
3        self.mass = mass3        self.mass = mass
4        self.uranium = uranium4        self.uranium = uranium
55
6    def get_uranium_quantity(self):6    def get_uranium_quantity(self):
7        return self.mass * self.uranium7        return self.mass * self.uranium
88
9    def get_mass(self):9    def get_mass(self):
10        return self.mass10        return self.mass
1111
1212
13class Person:13class Person:
14    def __init__(self, position):14    def __init__(self, position):
15        self.position = position15        self.position = position
1616
17    def get_position(self):17    def get_position(self):
18        return self.position18        return self.position
1919
20    def set_position(self, new_position):20    def set_position(self, new_position):
21        self.position = new_position21        self.position = new_position
2222
2323
24class Kid(Person):24class Kid(Person):
nn25    THRESHOLD_URANIUM = 20
26 
25    def __init__(self, position, initiative):27    def __init__(self, position, initiative):
26        super().__init__(position)28        super().__init__(position)
27        self.initiative = initiative29        self.initiative = initiative
28        self.candy_basket = []30        self.candy_basket = []
nn31        self.visited_hosts = set()
2932
30    def get_initiative(self):33    def get_initiative(self):
31        return self.initiative34        return self.initiative
3235
33    def add_candy(self, candy):36    def add_candy(self, candy):
34        self.candy_basket.append(candy)37        self.candy_basket.append(candy)
3538
nn39    def add_host(self, host):
40        self.visited_hosts.add(host)
41 
36    def is_critical(self):42    def is_critical(self):
37        total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket)43        total_uranium = sum(candy.get_uranium_quantity() for candy in self.candy_basket)
n38        return total_uranium > 20n44        return total_uranium > self.THRESHOLD_URANIUM
3945
4046
41class Host(Person):47class Host(Person):
42    def __init__(self, position, candies):48    def __init__(self, position, candies):
43        super().__init__(position)49        super().__init__(position)
n44        self.candy_basket = []n50        self.candy_basket = [Candy(*candy) for candy in candies]
45 
46        for candy_data in candies:
47            mass, uranium = candy_data
48            candy = Candy(mass, uranium)
49            self.candy_basket.append(candy)
5051
51    def remove_candy(self, selection_function):52    def remove_candy(self, selection_function):
52        if self.candy_basket:53        if self.candy_basket:
53            selected_candy = selection_function(self.candy_basket)54            selected_candy = selection_function(self.candy_basket)
54            self.candy_basket.remove(selected_candy)55            self.candy_basket.remove(selected_candy)
55            return selected_candy56            return selected_candy
56        else:57        else:
57            return None58            return None
5859
5960
nn61def find_closest_host(kid, hosts):
62    closest_host = None
63    min_distance = float('inf')
64 
65    for host in hosts:
66        if host not in kid.visited_hosts:
67            distance = abs(host.get_position()[0] - kid.get_position()[0]) + abs(host.get_position()[1] - kid.get_position()[1])
68            if distance < min_distance:
69                min_distance = distance
70                closest_host = host
71            elif distance == min_distance:
72                if host.get_position()[0] < closest_host.get_position()[0]:
73                    closest_host = host
74                elif host.get_position()[0] == closest_host.get_position()[0] and host.get_position()[1] < closest_host.get_position()[1]:
75                    closest_host = host
76 
77    return closest_host
78 
79 
60class FluxCapacitor:80class FluxCapacitor:
61    def __init__(self, participants):81    def __init__(self, participants):
62        self.participants = participants82        self.participants = participants
nn83        self.kids = [participant for participant in participants if isinstance(participant, Kid)]
84        self.hosts = [participant for participant in participants if isinstance(participant, Host)]
85 
86    @staticmethod
87    def select_max_mass_candy(candies):
88        return max(candies, key=lambda candy: candy.get_mass())
6389
64    def get_victim(self):90    def get_victim(self):
n65        kids = [participant for participant in self.participants if isinstance(participant, Kid)]n
66        hosts = [participant for participant in self.participants if isinstance(participant, Host)]
6791
68        victims = set()92        victims = set()
6993
70        while True:94        while True:
n71            for kid in kids:n
72                if not kid.candy_basket:
73                    continue
7495
n75                closest_host = min(n96            for kid in self.kids:
76                    (host for host in hosts if host.candy_basket),97                while len(kid.visited_hosts) is not len(self.hosts):
77                    key=lambda host: abs(host.get_position()[0] - kid.get_position()[0]) + abs(98                    closest_host = find_closest_host(kid, self.hosts)
78                        host.get_position()[1] - kid.get_position()[1])
79                )
8099
nn100                    if closest_host:
81                candy = closest_host.remove_candy(select_max_mass_candy)101                        candy = closest_host.remove_candy(self.select_max_mass_candy)
82                if candy:102                        if candy:
83                    kid.add_candy(candy)103                            kid.add_candy(candy)
104                            kid.add_host(closest_host)
105                            kid.set_position(closest_host.get_position())
84106
n85            for kid in kids:n
86                if kid.is_critical():107                    if kid.is_critical():
87                    victims.add(kid)108                        victims.add(kid)
109                        break
88110
t89            all_visited = all(not kid.candy_basket for kid in kids)t111            if not victims:
90            if all_visited:
91                break112                return None
92 113            else:
93        return victims114                return victims
94 
95 
96def select_max_mass_candy(candies):
97    return max(candies, key=lambda candy: candy.get_mass())
98 
99 
100if __name__ == '__main__':
101    candy = Candy(20, 0.3)
102    person = Person((1, 2))
103    kid = Kid((0, 0), 123)
104    host = Host((3, 4), [(1, 1.0), (2, 0.5)])
105    flux_capacitor = FluxCapacitor({kid, host})
106    flux_capacitor.get_victim()
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op