f | from math import dist | f | from math import dist |
| | | |
| | | |
| 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): |
n | return self.mass*self.uranium | n | return self.mass * self.uranium |
| | | |
| def get_mass(self): | | def get_mass(self): |
| return self.mass | | return self.mass |
| | | |
| def __str__(self) -> str: | | def __str__(self) -> str: |
| return f"({self.mass}, {self.uranium})" | | return f"({self.mass}, {self.uranium})" |
| | | |
| | | |
| 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 |
| | | |
| def __hash__(self) -> int: | | def __hash__(self) -> int: |
| return self.position.__hash__() | | return self.position.__hash__() |
| | | |
| | | |
| class Kid(Person): | | class Kid(Person): |
n | | n | |
| | | I_am_glowing_in_the_dark_magic_number = 20 |
| | | |
| def __init__(self, position, initiative): | | def __init__(self, position, initiative): |
| Person.__init__(self, position) | | Person.__init__(self, position) |
| self.initiative = initiative | | self.initiative = initiative |
| self.candies = [] | | self.candies = [] |
| 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): |
| if candy is not None: | | if candy is not None: |
| self.candies.append(candy) | | self.candies.append(candy) |
| | | |
| def is_critical(self): | | def is_critical(self): |
n | return sum([candy.get_uranium_quantity() for candy in self.candies]) > 20 | n | return sum([candy.get_uranium_quantity() for candy in self.candies]) > self.I_am_glowing_in_the_dark_magic_number |
| | | |
| def get_closest_host(self, hosts): | | def get_closest_host(self, hosts): |
| available_hosts = [ | | available_hosts = [ |
| host for host in hosts if host not in self.visited_hosts] | | host for host in hosts if host not in self.visited_hosts] |
| | | |
n | if len(available_hosts) == 0: | n | if not available_hosts: |
| return None | | return None |
| | | |
| closest_host = min(available_hosts, key=lambda host: | | closest_host = min(available_hosts, key=lambda host: |
| (dist(host.get_position(), self.get_position()), | | (dist(host.get_position(), self.get_position()), |
| *host.get_position()) | | *host.get_position()) |
| ) | | ) |
| | | |
| self.visited_hosts.add(closest_host) | | self.visited_hosts.add(closest_host) |
| self.set_position(closest_host.get_position()) | | self.set_position(closest_host.get_position()) |
| return closest_host | | return closest_host |
| | | |
| def __str__(self) -> str: | | def __str__(self) -> str: |
| candy_str = "" | | candy_str = "" |
| for candy in self.candies: | | for candy in self.candies: |
| candy_str += str(candy) + " " | | candy_str += str(candy) + " " |
| | | |
| hosts_str = "" | | hosts_str = "" |
| for host in self.visited_hosts: | | for host in self.visited_hosts: |
| hosts_str += str(host.get_position()) + " " | | hosts_str += str(host.get_position()) + " " |
| | | |
| return f"Kid at {self.position} with initiative {self.initiative} and candies {candy_str}visited hosts {hosts_str}" | | return f"Kid at {self.position} with initiative {self.initiative} and candies {candy_str}visited hosts {hosts_str}" |
| | | |
| | | |
| class Host(Person): | | class Host(Person): |
n | | n | |
| def __init__(self, position, candies): | | def __init__(self, position, candies): |
| Person.__init__(self, position) | | Person.__init__(self, position) |
| self.candies = [Candy(*candy) for candy in candies] | | self.candies = [Candy(*candy) for candy in candies] |
| | | |
| def remove_candy(self, func): | | def remove_candy(self, func): |
| if len(self.candies) == 0: | | if len(self.candies) == 0: |
| return None | | return None |
| | | |
| candy = func(self.candies) | | candy = func(self.candies) |
| self.candies.remove(candy) | | self.candies.remove(candy) |
| return candy | | return candy |
| | | |
| def give_away_happiness(self, kids, func): | | def give_away_happiness(self, kids, func): |
| for kid in sorted(kids, key=lambda kid: kid.get_initiative(), reverse=True): | | for kid in sorted(kids, key=lambda kid: kid.get_initiative(), reverse=True): |
| kid.add_candy(self.remove_candy(func)) | | kid.add_candy(self.remove_candy(func)) |
| | | |
| | | |
| class FluxCapacitor: | | class FluxCapacitor: |
n | | n | |
| def __init__(self, participants): | | def __init__(self, participants): |
n | self.participants = participants | n | self.kids = [participant for participant in participants if isinstance( |
| | | participant, Kid)] |
| | | self.hosts = [participant for participant in participants if isinstance( |
| | | participant, Host)] |
| | | |
| def get_victim(self): | | def get_victim(self): |
n | kids = [participant for participant in self.participants if isinstance( | n | |
| participant, Kid)] | | |
| hosts = [participant for participant in self.participants if isinstance( | | |
| participant, Host)] | | |
| | | |
n | def dead_kids_tell_no_tales(): | n | # RIP dead_kids_tell_no_tales() 05.11.2023 - 07.11.2023 :pepesad: |
| | | while True: |
| kids_to_hosts = { | | kids_to_hosts = { |
n | host: [] for host in hosts | n | host: [] for host in self.hosts |
| } | | } |
| | | |
n | for kid in kids: | n | for kid in self.kids: |
| host = kid.get_closest_host(hosts) | | host = kid.get_closest_host(self.hosts) |
| if host is not None: | | if host is not None: |
| kids_to_hosts[host].append(kid) | | kids_to_hosts[host].append(kid) |
| | | |
n | are_there_candies = False | n | self.are_there_candies = False |
| | | |
| def compare(candies): | | def compare(candies): |
n | nonlocal are_there_candies | n | |
| are_there_candies = True | | self.are_there_candies = True |
| | | return max(candies, key=lambda candy: candy.get_mass()) |
| | | |
n | return max( | n | |
| candies, key=lambda candy: candy.get_mass() | | |
| ) | | |
| | | |
| for host in hosts: | | for host in self.hosts: |
| host.give_away_happiness(kids_to_hosts[host], compare) | | host.give_away_happiness(kids_to_hosts[host], compare) |
| | | |
n | if (not are_there_candies): | n | if not self.are_there_candies: |
| return None | | return None |
| | | |
n | dead_kids = { | n | dead_kids = {kid for kid in self.kids if kid.is_critical()} |
| kid for kid in kids if kid.is_critical() | | |
| } | | |
| | | |
t | return dead_kids if len(dead_kids) > 0 else dead_kids_tell_no_tales() | t | if dead_kids: |
| | | return dead_kids |
| return dead_kids_tell_no_tales() | | |
07.11.2023 09:39