|
| 1 | +from dataclasses import dataclass |
| 2 | +from enum import Enum |
| 3 | +from typing import List, Dict |
| 4 | +from itertools import permutations |
| 5 | + |
| 6 | +unpreferred_OS_penalty = 100 |
| 7 | + |
| 8 | +class OperatingSystem(Enum): |
| 9 | + MACOS = "macOS" |
| 10 | + ARCH = "Arch Linux" |
| 11 | + UBUNTU = "Ubuntu" |
| 12 | + |
| 13 | +@dataclass(frozen=True) |
| 14 | +class Person: |
| 15 | + name: str |
| 16 | + age: int |
| 17 | + preferred_operating_system: tuple |
| 18 | + |
| 19 | +@dataclass(frozen=True) |
| 20 | +class Laptop: |
| 21 | + id: int |
| 22 | + manufacturer: str |
| 23 | + model: str |
| 24 | + screen_size_in_inches: float |
| 25 | + operating_system: OperatingSystem |
| 26 | + |
| 27 | +def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]: |
| 28 | + if len(people) != len(laptops): |
| 29 | + raise ValueError("Number of people must match number of laptops") |
| 30 | + |
| 31 | + best_assignment = None |
| 32 | + lowest_sadness = float("inf") |
| 33 | + |
| 34 | + for perm in permutations(laptops): |
| 35 | + total_sadness = 0 |
| 36 | + for person, laptop in zip(people, perm): |
| 37 | + if laptop.operating_system in person.preferred_operating_system: |
| 38 | + sadness = person.preferred_operating_system.index(laptop.operating_system) |
| 39 | + else: |
| 40 | + sadness = unpreferred_OS_penalty |
| 41 | + total_sadness += sadness |
| 42 | + |
| 43 | + if total_sadness < lowest_sadness: |
| 44 | + lowest_sadness = total_sadness |
| 45 | + best_assignment = perm |
| 46 | + |
| 47 | + return {person: laptop for person, laptop in zip(people, best_assignment)} |
| 48 | + |
| 49 | +laptops = [ |
| 50 | + Laptop(1, "Dell", "XPS 13", 13, OperatingSystem.ARCH), |
| 51 | + Laptop(2, "HP", "Spectre 15", 15, OperatingSystem.UBUNTU), |
| 52 | + Laptop(3, "Lenovo", "ThinkPad 14", 14, OperatingSystem.UBUNTU), |
| 53 | + Laptop(4, "Apple", "MacBook Air", 13, OperatingSystem.MACOS), |
| 54 | + Laptop(5, "Apple", "MacBook Pro", 16, OperatingSystem.MACOS), |
| 55 | + Laptop(6, "Dell", "Latitude", 15, OperatingSystem.ARCH), |
| 56 | + Laptop(7, "HP", "EliteBook", 13, OperatingSystem.MACOS), |
| 57 | + Laptop(8, "Lenovo", "Yoga", 14, OperatingSystem.UBUNTU) |
| 58 | +] |
| 59 | + |
| 60 | +people = [ |
| 61 | + Person("Alice", 29, (OperatingSystem.UBUNTU, OperatingSystem.MACOS)), |
| 62 | + Person("Bob", 34, (OperatingSystem.ARCH, OperatingSystem.UBUNTU)), |
| 63 | + Person("Charlie", 40, (OperatingSystem.MACOS, OperatingSystem.ARCH)), |
| 64 | + Person("Diana", 25, (OperatingSystem.MACOS,)), |
| 65 | + Person("Ethan", 31, (OperatingSystem.UBUNTU, OperatingSystem.ARCH)), |
| 66 | + Person("Fiona", 27, (OperatingSystem.MACOS, OperatingSystem.UBUNTU)), |
| 67 | + Person("George", 22, (OperatingSystem.ARCH, OperatingSystem.MACOS)), |
| 68 | + Person("Zara", 33, (OperatingSystem.ARCH, OperatingSystem.MACOS)) |
| 69 | +] |
| 70 | + |
| 71 | +assignment = allocate_laptops(people, laptops) |
| 72 | + |
| 73 | + |
| 74 | +for person, laptop in assignment.items(): |
| 75 | + person_sadness_score = ( |
| 76 | + person.preferred_operating_system.index(laptop.operating_system) |
| 77 | + if laptop.operating_system in person.preferred_operating_system |
| 78 | + else unpreferred_OS_penalty |
| 79 | + ) |
| 80 | + print(f"{person.name} was allocated {laptop.manufacturer} {laptop.model} " |
| 81 | + f"with {laptop.operating_system.value} (Score: {person_sadness_score})") |
| 82 | + |
| 83 | +total_sadness = sum( |
| 84 | + person.preferred_operating_system.index(laptop.operating_system) |
| 85 | + if laptop.operating_system in person.preferred_operating_system else unpreferred_OS_penalty |
| 86 | + for person, laptop in assignment.items() |
| 87 | +) |
| 88 | +print("\nTotal sadness:", total_sadness) |
0 commit comments