f | import math | f | import math |
| | | |
| | | |
| class Candy: | | class Candy: |
n | | n | |
| 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.uranium * self.mass | | return self.uranium * self.mass |
| | | |
| def get_mass(self): | | def get_mass(self): |
| return self.mass | | return self.mass |
| | | |
| | | |
| class Person: | | class Person: |
n | | n | |
| def __init__(self, position): | | def __init__(self, position): |
| self.position = position | | self.position = position |
| | | |
| def get_position(self): | | def get_position(self): |
| return self.position | | return self.position |
| | | |
| def set_position(self, position): | | def set_position(self, position): |
| self.position = position | | self.position = position |
| | | |
| | | |
| class Kid(Person): | | class Kid(Person): |
n | | n | |
| | | CRITICAL_QUANTITY = 20 |
| | | |
| def __init__(self, position, initiative): | | def __init__(self, position, initiative): |
| super().__init__(position) | | super().__init__(position) |
| self.initiative = initiative | | self.initiative = initiative |
| self.basket = [] | | self.basket = [] |
| self.visited_hosts = set() | | self.visited_hosts = set() |
| | | |
| def get_initiative(self): | | def get_initiative(self): |
| return self.initiative | | return self.initiative |
| | | |
| def add_candy(self, candy): | | def add_candy(self, candy): |
| self.basket.append(candy) | | self.basket.append(candy) |
| | | |
| def is_critical(self): | | def is_critical(self): |
| sum = 0 | | sum = 0 |
| for candy in self.basket: | | for candy in self.basket: |
| sum += candy.get_uranium_quantity() | | sum += candy.get_uranium_quantity() |
n | if sum > 20: | n | return sum > self.CRITICAL_QUANTITY |
| return True | | |
| return False | | |
| | | |
| def visit_closest_host(self, hosts): | | def visit_closest_host(self, hosts): |
| if len(self.visited_hosts) == len(hosts): | | if len(self.visited_hosts) == len(hosts): |
| return | | return |
| | | |
| closest_host = None | | closest_host = None |
| for host in hosts: | | for host in hosts: |
| if host in self.visited_hosts: | | if host in self.visited_hosts: |
| continue | | continue |
| if closest_host is None: | | if closest_host is None: |
| closest_host = host | | closest_host = host |
| if math.dist(self.position, host.get_position()) < math.dist(self.position, closest_host.get_position()): | | if math.dist(self.position, host.get_position()) < math.dist(self.position, closest_host.get_position()): |
| closest_host = host | | closest_host = host |
| elif math.dist(self.position, host.get_position()) == math.dist(self.position, closest_host.get_position()): | | elif math.dist(self.position, host.get_position()) == math.dist(self.position, closest_host.get_position()): |
| if (host.get_position()[0] < closest_host.get_position()[0] | | if (host.get_position()[0] < closest_host.get_position()[0] |
n | or host.get_position()[1] < closest_host.get_position()[1]): | n | or host.get_position()[1] < closest_host.get_position()[1]): |
| closest_host = host | | closest_host = host |
| | | |
| closest_host.visited_by_kid(self) | | closest_host.visited_by_kid(self) |
| self.visited_hosts.add(closest_host) | | self.visited_hosts.add(closest_host) |
| self.position = closest_host.get_position() | | self.position = closest_host.get_position() |
| | | |
| | | |
| class Host(Person): | | class Host(Person): |
n | | n | |
| def __init__(self, position, candies): | | def __init__(self, position, candies): |
| super().__init__(position) | | super().__init__(position) |
| self.visitors = [] | | self.visitors = [] |
| | | |
| self.candies = set() | | self.candies = set() |
| for pair in candies: | | for pair in candies: |
| candy = Candy(pair[0], pair[1]) | | candy = Candy(pair[0], pair[1]) |
| self.candies.add(candy) | | self.candies.add(candy) |
| | | |
| def remove_candy(self, remove_by_condition): | | def remove_candy(self, remove_by_condition): |
| if len(self.candies) == 0: | | if len(self.candies) == 0: |
| return None | | return None |
| removed = remove_by_condition(self.candies) | | removed = remove_by_condition(self.candies) |
| self.candies.discard(removed) | | self.candies.discard(removed) |
| return removed | | return removed |
| | | |
| def visited_by_kid(self, kid): | | def visited_by_kid(self, kid): |
| self.visitors.append(kid) | | self.visitors.append(kid) |
| | | |
| def treat(self): | | def treat(self): |
| self.visitors.sort(key=lambda x: x.get_initiative(), reverse=True) | | self.visitors.sort(key=lambda x: x.get_initiative(), reverse=True) |
| for visitor in self.visitors: | | for visitor in self.visitors: |
| candy = self.remove_candy(removal_condition) | | candy = self.remove_candy(removal_condition) |
| if candy: | | if candy: |
| visitor.add_candy(candy) | | visitor.add_candy(candy) |
| self.visitors.clear() | | self.visitors.clear() |
| | | |
| | | |
| class FluxCapacitor: | | class FluxCapacitor: |
n | | n | |
| def __init__(self, participants): | | def __init__(self, participants): |
| self.participants = participants | | self.participants = participants |
n | | n | self.hosts = [participant for participant in self.participants if isinstance(participant, Host)] |
| | | self.kids = [participant for participant in self.participants if isinstance(participant, Kid)] |
| | | |
| def get_victim(self): | | def get_victim(self): |
n | hosts = [participant for participant in self.participants if isinstance(participant, Host)] | n | |
| kids = [participant for participant in self.participants if isinstance(participant, Kid)] | | |
| | | |
| visitors = len(kids) | | visitors = len(self.kids) |
| | | |
| while visitors > 0: | | while visitors > 0: |
n | visitors = len(kids) | n | visitors = len(self.kids) |
| for kid in kids: | | for kid in self.kids: |
| kid.visit_closest_host(hosts) | | kid.visit_closest_host(self.hosts) |
| visitors -= len(kid.visited_hosts) == len(hosts) | | visitors -= len(kid.visited_hosts) == len(self.hosts) |
| | | |
n | for host in hosts: | n | for host in self.hosts: |
| host.treat() | | host.treat() |
| | | |
| critical_kids = set() | | critical_kids = set() |
t | for kid in kids: | t | for kid in self.kids: |
| if kid.is_critical(): | | if kid.is_critical(): |
| critical_kids.add(kid) | | critical_kids.add(kid) |
| | | |
| if len(critical_kids) > 0: | | if len(critical_kids) > 0: |
| return critical_kids | | return critical_kids |
| | | |
| return None | | return None |
| | | |
| | | |
| def removal_condition(candies): | | def removal_condition(candies): |
| largest_candy = list(candies)[0] | | largest_candy = list(candies)[0] |
| for candy in candies: | | for candy in candies: |
| if candy.get_mass() > largest_candy.get_mass(): | | if candy.get_mass() > largest_candy.get_mass(): |
| largest_candy = candy | | largest_candy = candy |
| | | |
| return largest_candy | | return largest_candy |