Домашни > Хелоуин в Припят > Решения > Решението на Ивайло Кънчев

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

10 точки общо

12 успешни теста
0 неуспешни теста
Код

  1class Candy:
  2
  3    def __init__(self, mass: int, uranium: float):
  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: tuple):
 17        self._position = position
 18
 19    def get_position(self):
 20        return self._position
 21
 22    def set_position(self, position: tuple):
 23        self._position = position
 24
 25
 26class Kid(Person):
 27
 28    _critical_mass = 20
 29
 30    def __init__(self, position: tuple, initiative):
 31        super().__init__(position)
 32        self._initiative = initiative
 33        self._bag = []
 34
 35    def get_initiative(self):
 36        return self._initiative
 37
 38    def add_candy(self, candy: Candy):
 39        self._bag.append(candy)
 40
 41    def is_critical(self):
 42        radianion = 0
 43        for candy in self._bag:
 44            radianion += candy.get_uranium_quantity()
 45        return radianion > self._critical_mass
 46
 47
 48class Host(Person):
 49
 50    def __init__(self, position: tuple, candies: list):
 51        super().__init__(position)
 52        self._candies = []
 53        for candy in candies:
 54            self._candies.append(Candy(*candy))
 55
 56    def remove_candy(self, candy_criteria):
 57        if self._candies:
 58            selected_candy = candy_criteria(self._candies)
 59            self._candies.remove(selected_candy)
 60            return selected_candy
 61        return None
 62
 63
 64class FluxCapacitor:
 65
 66    def __init__(self, participants: set):
 67        self._kids = set()
 68        self._hosts = set()
 69        for person in participants:
 70            if isinstance(person, Kid):
 71                self._kids.add(person)
 72            else:
 73                self._hosts.add(person)
 74        self._kids = sorted(self._kids, key=lambda kid: kid.get_initiative(), reverse=True)
 75
 76    def get_victim(self):
 77        if len(self._hosts) == 0:
 78            return None
 79
 80        unvisited = {}
 81        for kid in self._kids:
 82            unvisited[kid.get_initiative()] = set()
 83            for host in self._hosts:
 84                unvisited[kid.get_initiative()].add(host.get_position())
 85
 86        while unvisited:
 87            for kid in self._kids:
 88                curr_pos = kid.get_position()
 89                next_pos =FluxCapacitor.closest_host(curr_pos, unvisited[kid.get_initiative()])
 90                kid.set_position(next_pos)
 91                for host in self._hosts:
 92                    if next_pos == host.get_position():
 93                        candy = host.remove_candy(FluxCapacitor.candy_criteria)
 94                        break
 95                if candy is not None:
 96                    kid.add_candy(candy)
 97                unvisited[kid.get_initiative()].remove(next_pos)
 98                if len(unvisited[kid.get_initiative()]) == 0:
 99                    unvisited.pop(kid.get_initiative())
100
101            kids_with_critical_mass = self._critical_mass_check()
102            if kids_with_critical_mass:
103                return kids_with_critical_mass
104
105        return None
106
107    def _critical_mass_check(self):
108        kids_with_critical_mass = set()
109        for kid in self._kids:
110            if kid.is_critical():
111                kids_with_critical_mass.add(kid)
112        return kids_with_critical_mass
113
114    @staticmethod
115    def closest_host(pos: tuple, remaining_hosts: set):
116        closest_dist = None
117
118        for host in remaining_hosts:
119            dist = ((pos[0] - host[0]) * (pos[0] - host[0])
120                        + (pos[1] - host[1]) * (pos[1] - host[1]))
121            if (closest_dist is None or dist < closest_dist
122                or (dist == closest_dist and next_pos[0] < pos[0])
123                or (dist == closest_dist and next_pos[0] == pos[0] and next_pos[1] < pos[1])):
124                closest_dist = dist
125                next_pos = host
126        return next_pos
127
128    @staticmethod
129    def candy_criteria(candies: list[Candy]):
130        chosen_candy = Candy(0, 0)
131        for candy in candies:
132            if candy.get_mass() > chosen_candy.get_mass():
133                chosen_candy = candy
134        return chosen_candy

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

OK

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

f1class Candy:f1class Candy:
nn2 
2    def __init__(self, mass: int, uranium: float):3    def __init__(self, mass: int, uranium: float):
3        self._mass = mass4        self._mass = mass
4        self._uranium = uranium5        self._uranium = uranium
56
6    def get_uranium_quantity(self):7    def get_uranium_quantity(self):
7        return self._mass * self._uranium8        return self._mass * self._uranium
89
9    def get_mass(self):10    def get_mass(self):
10        return self._mass11        return self._mass
1112
1213
13class Person:14class Person:
nn15 
14    def __init__(self, position: tuple):16    def __init__(self, position: tuple):
15        self._position = position17        self._position = position
1618
17    def get_position(self):19    def get_position(self):
18        return self._position20        return self._position
1921
20    def set_position(self, position: tuple):22    def set_position(self, position: tuple):
21        self._position = position23        self._position = position
2224
2325
24class Kid(Person):26class Kid(Person):
nn27 
25    _critical_mass = 2028    _critical_mass = 20
2629
27    def __init__(self, position: tuple, initiative):30    def __init__(self, position: tuple, initiative):
28        super().__init__(position)31        super().__init__(position)
29        self._initiative = initiative32        self._initiative = initiative
30        self._bag = []33        self._bag = []
3134
32    def get_initiative(self):35    def get_initiative(self):
33        return self._initiative36        return self._initiative
3437
35    def add_candy(self, candy: Candy):38    def add_candy(self, candy: Candy):
36        self._bag.append(candy)39        self._bag.append(candy)
3740
38    def is_critical(self):41    def is_critical(self):
39        radianion = 042        radianion = 0
40        for candy in self._bag:43        for candy in self._bag:
41            radianion += candy.get_uranium_quantity()44            radianion += candy.get_uranium_quantity()
42        return radianion > self._critical_mass45        return radianion > self._critical_mass
4346
4447
45class Host(Person):48class Host(Person):
nn49 
46    def __init__(self, position: tuple, candies: list):50    def __init__(self, position: tuple, candies: list):
47        super().__init__(position)51        super().__init__(position)
48        self._candies = []52        self._candies = []
49        for candy in candies:53        for candy in candies:
n50            self._candies.append(Candy(candy[0], candy[1]))n54            self._candies.append(Candy(*candy))
5155
52    def remove_candy(self, candy_criteria):56    def remove_candy(self, candy_criteria):
53        if self._candies:57        if self._candies:
54            selected_candy = candy_criteria(self._candies)58            selected_candy = candy_criteria(self._candies)
55            self._candies.remove(selected_candy)59            self._candies.remove(selected_candy)
56            return selected_candy60            return selected_candy
57        return None61        return None
5862
5963
60class FluxCapacitor:64class FluxCapacitor:
nn65 
61    def __init__(self, participants: set):66    def __init__(self, participants: set):
62        self._kids = set()67        self._kids = set()
63        self._hosts = set()68        self._hosts = set()
64        for person in participants:69        for person in participants:
65            if isinstance(person, Kid):70            if isinstance(person, Kid):
66                self._kids.add(person)71                self._kids.add(person)
67            else:72            else:
68                self._hosts.add(person)73                self._hosts.add(person)
69        self._kids = sorted(self._kids, key=lambda kid: kid.get_initiative(), reverse=True)74        self._kids = sorted(self._kids, key=lambda kid: kid.get_initiative(), reverse=True)
7075
71    def get_victim(self):76    def get_victim(self):
72        if len(self._hosts) == 0:77        if len(self._hosts) == 0:
73            return None78            return None
7479
75        unvisited = {}80        unvisited = {}
76        for kid in self._kids:81        for kid in self._kids:
77            unvisited[kid.get_initiative()] = set()82            unvisited[kid.get_initiative()] = set()
78            for host in self._hosts:83            for host in self._hosts:
79                unvisited[kid.get_initiative()].add(host.get_position())84                unvisited[kid.get_initiative()].add(host.get_position())
8085
81        while unvisited:86        while unvisited:
82            for kid in self._kids:87            for kid in self._kids:
n83                curr_position = kid.get_position()n88                curr_pos = kid.get_position()
84                next_position = self._closest_host(curr_position, unvisited[kid.get_initiative()])89                next_pos =FluxCapacitor.closest_host(curr_pos, unvisited[kid.get_initiative()])
85                kid.set_position(next_position)90                kid.set_position(next_pos)
86                candy: Candy
87                for host in self._hosts:91                for host in self._hosts:
n88                    if next_position == host.get_position():n92                    if next_pos == host.get_position():
89                        candy = host.remove_candy(candy_criteria)93                        candy = host.remove_candy(FluxCapacitor.candy_criteria)
90                        break94                        break
91                if candy is not None:95                if candy is not None:
92                    kid.add_candy(candy)96                    kid.add_candy(candy)
n93                unvisited[kid.get_initiative()].remove(next_position)n97                unvisited[kid.get_initiative()].remove(next_pos)
94                if len(unvisited[kid.get_initiative()]) == 0:98                if len(unvisited[kid.get_initiative()]) == 0:
95                    unvisited.pop(kid.get_initiative())99                    unvisited.pop(kid.get_initiative())
96100
97            kids_with_critical_mass = self._critical_mass_check()101            kids_with_critical_mass = self._critical_mass_check()
98            if kids_with_critical_mass:102            if kids_with_critical_mass:
99                return kids_with_critical_mass103                return kids_with_critical_mass
100104
101        return None105        return None
102106
n103    def _closest_host(self, pos: tuple, remaining_hosts: set):n
104        closest_dist = 10000000
105        next_pos = (100000, 100000)
106 
107        for host in remaining_hosts:
108            dist = ((pos[0] - host[0]) * (pos[0] - host[0])
109                        + (pos[1] - host[1]) * (pos[1] - host[1]))
110            if (dist < closest_dist
111                or (dist == closest_dist and next_pos[0] < pos[0])
112                or (dist == closest_dist and next_pos[0] == pos[0] and next_pos[1] < pos[1])):
113                closest_dist = dist
114                next_pos = host
115        return next_pos
116 
117    def _critical_mass_check(self):107    def _critical_mass_check(self):
118        kids_with_critical_mass = set()108        kids_with_critical_mass = set()
119        for kid in self._kids:109        for kid in self._kids:
120            if kid.is_critical():110            if kid.is_critical():
121                kids_with_critical_mass.add(kid)111                kids_with_critical_mass.add(kid)
122        return kids_with_critical_mass112        return kids_with_critical_mass
123113
tt114    @staticmethod
115    def closest_host(pos: tuple, remaining_hosts: set):
116        closest_dist = None
117 
118        for host in remaining_hosts:
119            dist = ((pos[0] - host[0]) * (pos[0] - host[0])
120                        + (pos[1] - host[1]) * (pos[1] - host[1]))
121            if (closest_dist is None or dist < closest_dist
122                or (dist == closest_dist and next_pos[0] < pos[0])
123                or (dist == closest_dist and next_pos[0] == pos[0] and next_pos[1] < pos[1])):
124                closest_dist = dist
125                next_pos = host
126        return next_pos
127 
128    @staticmethod
124def candy_criteria(candies: list[Candy]):129    def candy_criteria(candies: list[Candy]):
125    chosen_candy = Candy(0, 0)130        chosen_candy = Candy(0, 0)
126    for candy in candies:131        for candy in candies:
127        if candy.get_mass() > chosen_candy.get_mass():132            if candy.get_mass() > chosen_candy.get_mass():
128            chosen_candy = candy133                chosen_candy = candy
129    return chosen_candy134        return chosen_candy
Legends
Colors
 Added 
Changed
Deleted
Links
(f)irst change
(n)ext change
(t)op