From d99160553c940bccc61b6812d50250d0fb09b66f Mon Sep 17 00:00:00 2001 From: Mikiyas-STP Date: Thu, 16 Oct 2025 20:45:52 +0100 Subject: [PATCH 1/2] laptop allocation --- laptopalloc.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 laptopalloc.py diff --git a/laptopalloc.py b/laptopalloc.py new file mode 100644 index 0000000..dbfe685 --- /dev/null +++ b/laptopalloc.py @@ -0,0 +1,69 @@ +#import Python tools for structured data (dataclass), enumerations (Enum), and type hints (List, Dict) +from dataclasses import dataclass +from enum import Enum +from typing import List, Dict, Tuple +#Define a fixed set of operating systems as an enum to avoid typos and enforce valid values +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" +#Rep a person with a name, age, and ordered preferences of operating systems(immutable) +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_system: tuple[OperatingSystem, ...] + +#Repr a laptop with identifying info, screen size, and its operating system +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: OperatingSystem + +#Main function to assign exactly one laptop per person while minimizing “sadness” +def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]: + sadness_list: List[Tuple[int, Person, Laptop]] = [] + #Compute sadness for each laptop for each person (0 = best match, 100 = not preferred) + for person in people: + for laptop in laptops: + if laptop.operating_system in person.preferred_operating_system: + sadness = person.preferred_operating_system.index(laptop.operating_system) + else: + sadness = 100 + sadness_list.append((sadness, person, laptop)) + +# Sort by sadness (lowest first) + sadness_list.sort(key=lambda x: x[0]) +#Track assigned laptops and people to ensure uniqueness + allocations: Dict[Person, Laptop] = {} + allocated_laptops = set() + +#Greedily allocate laptops to minimise sadness + for sadness, person, laptop in sadness_list: + if person not in allocations and laptop.id not in allocated_laptops: + allocations[person] = laptop + allocated_laptops.add(laptop.id) + + return allocations + + + + + + +#example usage +people = [ + Person("Imran", 22, (OperatingSystem.UBUNTU, OperatingSystem.ARCH, OperatingSystem.MACOS)), + Person("Eliza", 34, (OperatingSystem.ARCH, OperatingSystem.UBUNTU)), +] +laptops = [ + Laptop(1, "Dell", "XPS 13", 13, OperatingSystem.ARCH), + Laptop(2, "Apple", "MacBook", 13, OperatingSystem.MACOS), + Laptop(3, "Dell", "XPS 15", 15, OperatingSystem.UBUNTU), +] +allocations = allocate_laptops(people, laptops) +for person, laptop in allocations.items(): + print(f"{person.name} gets {laptop.manufacturer} {laptop.model} ({laptop.operating_system.value})") \ No newline at end of file From 2935067cd0dced892d1a5963c9bdece3060898ac Mon Sep 17 00:00:00 2001 From: mikiyas-stp Date: Thu, 5 Feb 2026 22:57:56 +0000 Subject: [PATCH 2/2] Refactor laptop allocation to greedy approach for efficiency and clarity --- laptopalloc.py | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/laptopalloc.py b/laptopalloc.py index dbfe685..7867c1f 100644 --- a/laptopalloc.py +++ b/laptopalloc.py @@ -1,7 +1,8 @@ #import Python tools for structured data (dataclass), enumerations (Enum), and type hints (List, Dict) from dataclasses import dataclass from enum import Enum -from typing import List, Dict, Tuple +from typing import List, Dict + #Define a fixed set of operating systems as an enum to avoid typos and enforce valid values class OperatingSystem(Enum): MACOS = "macOS" @@ -25,36 +26,32 @@ class Laptop: #Main function to assign exactly one laptop per person while minimizing “sadness” def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]: - sadness_list: List[Tuple[int, Person, Laptop]] = [] - #Compute sadness for each laptop for each person (0 = best match, 100 = not preferred) - for person in people: - for laptop in laptops: - if laptop.operating_system in person.preferred_operating_system: - sadness = person.preferred_operating_system.index(laptop.operating_system) - else: - sadness = 100 - sadness_list.append((sadness, person, laptop)) - -# Sort by sadness (lowest first) - sadness_list.sort(key=lambda x: x[0]) -#Track assigned laptops and people to ensure uniqueness - allocations: Dict[Person, Laptop] = {} + allocations: Dict[Person, Laptop] = {} # store which laptop each person gets allocated_laptops = set() + for person in people: + # Try preferred operating systems in order + for preferred_os in person.preferred_operating_system: + # find the first unallocated laptop with this OS + laptop = next( + (l for l in laptops if l.operating_system == preferred_os and l.id not in allocated_laptops), + None + ) + if laptop: + allocations[person] = laptop + allocated_laptops.add(laptop.id) + break # stop checking once a laptop is assigned -#Greedily allocate laptops to minimise sadness - for sadness, person, laptop in sadness_list: - if person not in allocations and laptop.id not in allocated_laptops: - allocations[person] = laptop - allocated_laptops.add(laptop.id) + # Fallback: if no preferred OS laptop is available, assign any remaining laptop + if person not in allocations: + for laptop in laptops: + if laptop.id not in allocated_laptops: + allocations[person] = laptop + allocated_laptops.add(laptop.id) + break return allocations - - - - -#example usage people = [ Person("Imran", 22, (OperatingSystem.UBUNTU, OperatingSystem.ARCH, OperatingSystem.MACOS)), Person("Eliza", 34, (OperatingSystem.ARCH, OperatingSystem.UBUNTU)),