f | import math | f | import math |
| | | |
| | | |
| class Candy: | | class Candy: |
| | | |
| def __init__(self, mass: int, uranium: int): | | def __init__(self, mass: int, uranium: int): |
| 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: tuple): | | def __init__(self, position: tuple): |
| self.position = position | | self.position = position |
| | | |
| def get_position(self): | | def get_position(self): |
| return self.position | | return self.position |
| | | |
| def set_position(self, new_position: tuple): | | def set_position(self, new_position: tuple): |
| self.position = new_position | | self.position = new_position |
| | | |
| | | |
| class Kid(Person): | | class Kid(Person): |
n | | n | CRITICAL_MASS = 20 |
| | | |
| def __init__(self, position: tuple, initiative: int): | | def __init__(self, position: tuple, initiative: int): |
| self.position = position | | self.position = position |
| self.initiative = initiative | | self.initiative = initiative |
| self.candies = [] | | self.candies = [] |
| self.visited = set() | | self.visited = set() |
| | | |
| def get_initiative(self): | | def get_initiative(self): |
| return self.initiative | | return self.initiative |
| | | |
| def add_candy(self, candy: Candy): | | def add_candy(self, candy: Candy): |
| self.candies.append(candy) | | self.candies.append(candy) |
| | | |
| def is_critical(self): | | def is_critical(self): |
| uranium_mass = 0 | | uranium_mass = 0 |
| for candy in self.candies: | | for candy in self.candies: |
| uranium_mass += candy.get_uranium_quantity() | | uranium_mass += candy.get_uranium_quantity() |
| | | |
n | if uranium_mass > 20: | n | return uranium_mass > self.CRITICAL_MASS |
| return True | | |
| else: | | |
| return False | | |
| | | |
| | | |
| class Host(Person): | | class Host(Person): |
| | | |
| def __init__(self, position: tuple, candies: list): | | def __init__(self, position: tuple, candies: list): |
| self.candies = [] | | self.candies = [] |
| for candy in candies: | | for candy in candies: |
| self.candies.append(Candy(candy[0], candy[1])) | | self.candies.append(Candy(candy[0], candy[1])) |
| self.position = position | | self.position = position |
| | | |
| def remove_candy(self, condition): | | def remove_candy(self, condition): |
| if len(self.candies) == 0: | | if len(self.candies) == 0: |
| return None | | return None |
| candy = condition(self.candies) | | candy = condition(self.candies) |
| self.candies.remove(candy) | | self.candies.remove(candy) |
| return candy | | return candy |
| | | |
| | | |
| class FluxCapacitor: | | class FluxCapacitor: |
| | | |
| def __init__(self, participants: set): | | def __init__(self, participants: set): |
| self.kids = [] | | self.kids = [] |
| self.hosts = [] | | self.hosts = [] |
| | | |
| for person in participants: | | for person in participants: |
| if type(person) is Kid: | | if type(person) is Kid: |
| self.kids.append(person) | | self.kids.append(person) |
| else: | | else: |
| self.hosts.append(person) | | self.hosts.append(person) |
| self.kids.sort(reverse=True, key=lambda kid: kid.get_initiative()) | | self.kids.sort(reverse=True, key=lambda kid: kid.get_initiative()) |
| | | |
| def get_victim(self): | | def get_victim(self): |
| dead_kids = set() | | dead_kids = set() |
| if len(self.kids) == 0: | | if len(self.kids) == 0: |
| return None | | return None |
| | | |
| while True: | | while True: |
n | kid: Kid | n | |
| for kid in self.kids: | | for kid in self.kids: |
| closest_host = None | | closest_host = None |
| distance = float('inf') | | distance = float('inf') |
n | host: Host | n | |
| for host in self.hosts: | | for host in self.hosts: |
| if host in kid.visited: | | if host in kid.visited: |
| continue | | continue |
| new_distance = math.dist(kid.get_position(), host.get_position()) | | new_distance = math.dist(kid.get_position(), host.get_position()) |
| if distance > new_distance: | | if distance > new_distance: |
| distance = new_distance | | distance = new_distance |
| closest_host = host | | closest_host = host |
| elif distance == new_distance: | | elif distance == new_distance: |
| if closest_host.get_position() > host.get_position(): | | if closest_host.get_position() > host.get_position(): |
| closest_host = host | | closest_host = host |
| | | |
| if closest_host is None: | | if closest_host is None: |
| return None | | return None |
| taken_candy = closest_host.remove_candy(determine_max_mass) | | taken_candy = closest_host.remove_candy(determine_max_mass) |
| | | |
| if taken_candy is not None: | | if taken_candy is not None: |
| kid.add_candy(taken_candy) | | kid.add_candy(taken_candy) |
| kid.visited.add(closest_host) | | kid.visited.add(closest_host) |
| | | |
| if kid.is_critical(): | | if kid.is_critical(): |
| dead_kids.add(kid) | | dead_kids.add(kid) |
| | | |
n | if len(dead_kids) != 0: | n | if dead_kids: |
| return dead_kids | | return dead_kids |
| | | |
| | | |
| def determine_max_mass(candies: list): | | def determine_max_mass(candies: list): |
| max = 0 | | max = 0 |
t | candy: Candy | t | |
| for candy in candies: | | for candy in candies: |
| if max < candy.get_mass(): | | if max < candy.get_mass(): |
| max = candy.get_mass() | | max = candy.get_mass() |
| max_candy = candy | | max_candy = candy |
| | | |
| return max_candy | | return max_candy |