n | class Bascket: | n | class Basket: |
| def __init__(self): | | def __init__(self): |
| self.candies = [] | | self.candies = [] |
| self.candy_givers = [] | | self.candy_givers = [] |
| | | |
| def add_candy(self, candy): | | def add_candy(self, candy): |
| self.candies.append(candy) | | self.candies.append(candy) |
| | | |
| def add_giver(self, giver): | | def add_giver(self, giver): |
| self.candy_givers.append(giver) | | self.candy_givers.append(giver) |
| | | |
| def remove_candy(self, candy): | | def remove_candy(self, candy): |
| self.candies.remove(candy) | | self.candies.remove(candy) |
| | | |
| def get_candies(self): | | def get_candies(self): |
| return self.candies | | return self.candies |
| | | |
| def fill(self, candies): | | def fill(self, candies): |
| self.candies = candies | | self.candies = candies |
| | | |
| | | |
| class Candy: | | class Candy: |
| def __init__(self, mass, uranium): | | def __init__(self, mass, uranium): |
| self.mass = mass | | self.mass = mass |
| self.uranium = uranium | | self.uranium = uranium |
| | | |
| def get_uranium_quantity(self): | | def get_uranium_quantity(self): |
| return self.mass * self.uranium | | return self.mass * self.uranium |
| | | |
| def get_mass(self): | | def get_mass(self): |
| return self.mass | | return self.mass |
| | | |
| | | |
| class Person: | | class Person: |
| def __init__(self, position): | | def __init__(self, position): |
| self.position = position | | self.position = position |
n | self.bascket = Bascket() | n | self.basket = Basket() |
| | | |
| def get_position(self): | | def get_position(self): |
| return self.position | | return self.position |
| | | |
| def set_position(self, new_position): | | def set_position(self, new_position): |
| self.position = new_position | | self.position = new_position |
| | | |
| def get_distance(self, other_person): | | def get_distance(self, other_person): |
| return (self.position[0] - other_person.position[0]) ** 2 + (self.position[1] - other_person.position[1]) ** 2 | | return (self.position[0] - other_person.position[0]) ** 2 + (self.position[1] - other_person.position[1]) ** 2 |
| | | |
| | | |
| class Kid(Person): | | class Kid(Person): |
n | | n | MIN_URANIUM_TO_UNLOCK_POWER = 20 |
| | | |
| def __init__(self, position, initiative): | | def __init__(self, position, initiative): |
| super().__init__(position) | | super().__init__(position) |
| self.initiative = initiative | | self.initiative = initiative |
| | | |
| def get_initiative(self): | | def get_initiative(self): |
| return self.initiative | | return self.initiative |
| | | |
| def add_candy(self, candy): | | def add_candy(self, candy): |
n | self.bascket.add_candy(candy) | n | self.basket.add_candy(candy) |
| | | |
| def is_critical(self): | | def is_critical(self): |
n | return sum(candy.get_uranium_quantity() for candy in self.bascket.get_candies()) > 20 | n | return sum(candy.get_uranium_quantity() for candy in self.basket.get_candies()) > self.MIN_URANIUM_TO_UNLOCK_POWER |
| | | |
| def visit_closest_host(self, hosts): | | def visit_closest_host(self, hosts): |
| min_distance = None | | min_distance = None |
| closest_host = None | | closest_host = None |
n | | n | |
| for host in hosts: | | for host in hosts: |
| distance = self.get_distance(host) | | distance = self.get_distance(host) |
| host_position = host.get_position() | | host_position = host.get_position() |
n | | n | closest_position = closest_host.get_position() if closest_host else None |
| | | |
| if host in self.bascket.candy_givers: | | if host in self.basket.candy_givers: |
| continue | | continue |
n | | n | |
| if ( | | if ( |
| min_distance is None or | | min_distance is None or |
n | distance < min_distance or | n | (distance, host_position[0], host_position[1]) < (min_distance, closest_position[0], closest_position[1]) |
| distance == min_distance and ( | | |
| host_position[0] < closest_host.get_position()[0] or | | |
| host_position[1] < closest_host.get_position()[1] | | |
| ) | | |
| ): | | ): |
| min_distance = distance | | min_distance = distance |
| closest_host = host | | closest_host = host |
| | | |
| return closest_host | | return closest_host |
| | | |
| | | |
| class Host(Person): | | class Host(Person): |
| def __init__(self, position, candies): | | def __init__(self, position, candies): |
| super().__init__(position) | | super().__init__(position) |
n | self.bascket.fill([Candy(mass, uranium) for mass, uranium in candies]) | n | self.basket.fill([Candy(mass, uranium) for mass, uranium in candies]) |
| | | |
| def remove_candy(self, candy_picker): | | def remove_candy(self, candy_picker): |
n | if not len(self.bascket.get_candies()): | n | if not len(self.basket.get_candies()): |
| return | | return |
n | | n | |
| picked_candy = candy_picker(self.bascket.get_candies()) | | picked_candy = candy_picker(self.basket.get_candies()) |
| self.bascket.remove_candy(picked_candy) | | self.basket.remove_candy(picked_candy) |
| | | |
| return picked_candy | | return picked_candy |
| | | |
| def give_candy(self, kids, candy_picker): | | def give_candy(self, kids, candy_picker): |
| kids = sorted(kids, key=lambda kid: kid.initiative, reverse=True) | | kids = sorted(kids, key=lambda kid: kid.initiative, reverse=True) |
| for kid in kids: | | for kid in kids: |
| picked_candy = self.remove_candy(candy_picker) | | picked_candy = self.remove_candy(candy_picker) |
n | kid.bascket.add_giver(self) | n | kid.basket.add_giver(self) |
| if picked_candy: | | if picked_candy: |
| kid.add_candy(picked_candy) | | kid.add_candy(picked_candy) |
| | | |
| | | |
| class FluxCapacitor: | | class FluxCapacitor: |
| def __init__(self, participants): | | def __init__(self, participants): |
| self.participants = participants | | self.participants = participants |
| | | |
| def get_victim(self): | | def get_victim(self): |
n | kids = [participant for participant in self.participants if type(participant) == Kid] | n | kids = [participant for participant in self.participants if type(participant) is Kid] |
| hosts = [participant for participant in self.participants if type(participant) == Host] | | hosts = [participant for participant in self.participants if type(participant) is Host] |
| kids_who_glow_in_the_dark = set() | | kids_who_glow_in_the_dark = set() |
| | | |
| while not len(kids_who_glow_in_the_dark): | | while not len(kids_who_glow_in_the_dark): |
| visitings = [] | | visitings = [] |
n | | n | |
| for kid in kids: | | for kid in kids: |
| closest_host = kid.visit_closest_host(hosts) | | closest_host = kid.visit_closest_host(hosts) |
| if closest_host: | | if closest_host: |
| visitings.append((kid, closest_host)) | | visitings.append((kid, closest_host)) |
| kid.set_position(closest_host.get_position()) | | kid.set_position(closest_host.get_position()) |
n | | n | |
| if not len(visitings): | | if not len(visitings): |
| return | | return |
n | | n | |
| for host in hosts: | | for host in hosts: |
| host.give_candy( | | host.give_candy( |
| (kid_host_pair[0] for kid_host_pair in visitings if kid_host_pair[1] == host), | | (kid_host_pair[0] for kid_host_pair in visitings if kid_host_pair[1] == host), |
n | get_biggest_mass_candy | n | self.get_biggest_mass_candy |
| ) | | ) |
n | | n | |
| kids_who_glow_in_the_dark = {kid for kid in kids if kid.is_critical()} | | kids_who_glow_in_the_dark = {kid for kid in kids if kid.is_critical()} |
| | | |
| return kids_who_glow_in_the_dark | | return kids_who_glow_in_the_dark |
| | | |
t | | t | @staticmethod |
| def get_biggest_mass_candy(candies): | | def get_biggest_mass_candy(candies): |
| return max(candies, key=lambda candy: candy.get_mass()) | | return max(candies, key=lambda candy: candy.get_mass()) |