diff --git a/implement-laptop-allocation/README.md b/implement-laptop-allocation/README.md new file mode 100644 index 00000000..ce85692d --- /dev/null +++ b/implement-laptop-allocation/README.md @@ -0,0 +1,42 @@ +In the prep, there was an exercise around finding possible laptops for a group of people. + +Your exercise is to extend this to actually allocate laptops to the people. + +Given these class definitions: + +from dataclasses import dataclass +from enum import Enum +from typing import List + +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + +@dataclass(frozen=True) +class Person: + name: str + age: int + # Sorted in order of preference, most preferred is first. + preferred_operating_system: List[OperatingSystem] + + +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: OperatingSystem +Write a function with this signature: + +def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]: +Every person should be allocated exactly one laptop. + +If we define "sadness" as the number of places down in someone's ranking the operating system the ended up with (i.e. if your preferences were [UBUNTU, ARCH, MACOS] and you were allocated a MACOS machine your sadness would be 2), we want to minimise the total sadness of all people. If we allocate someone a laptop with an operating system not in their preferred list, treat them as having a sadness of 100. + +Maximum time in hours +3 + +How to submit +Submit a PR to this repo containing your function (and any supporting code). diff --git a/implement-laptop-allocation/main.py b/implement-laptop-allocation/main.py new file mode 100644 index 00000000..61ea5f57 --- /dev/null +++ b/implement-laptop-allocation/main.py @@ -0,0 +1,56 @@ +from dataclasses import dataclass +from enum import Enum +from typing import List, Dict +from itertools import permutations + + +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + +@dataclass(frozen=True) +class Person: + name: str + age: int + # Sorted in order of preference, most preferred is first. + preferred_operating_system: List[OperatingSystem] + + +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: OperatingSystem + + +def sadness(person: Person, laptop: Laptop) ->int: + try: + return person.preferred_operating_system.index(laptop.operating_system) + except ValueError: + return 100 + + +def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]: + + best_scenario_assignment = None + best_total_sadness = float("inf") + + for scenario in permutations(laptops): + total_sadness = 0 + + #find the sadness level for each scenario + for person, laptop in zip(people, scenario): + total_sadness += sadness(person, laptop) + + #Check if this is the best scenario so far + if total_sadness < best_total_sadness: + best_total_sadness = total_sadness + best_scenario_assignment = scenario + + # Convert best_scenario_assignment into Dict[Person, Laptop] + return {person: laptop for person, laptop in zip(people, best_scenario_assignment)} + +