From 964c731898fdaad8843aca513f96faac4861298c Mon Sep 17 00:00:00 2001 From: Emilianouz <135679131+Emilianouz@users.noreply.github.com> Date: Thu, 18 Dec 2025 16:09:07 +0000 Subject: [PATCH 1/3] laptop allocation exercise --- laptop-allocation.py | 62 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 laptop-allocation.py diff --git a/laptop-allocation.py b/laptop-allocation.py new file mode 100644 index 000000000..d5f77b985 --- /dev/null +++ b/laptop-allocation.py @@ -0,0 +1,62 @@ +#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), +# 0 1 2 100 +#we want to minimize 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. + +from dataclasses import dataclass +from enum import Enum +from typing import List, Dict, Optional + + +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_system: List[OperatingSystem] + assigned_laptop: Optional[int] = None + +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: OperatingSystem + assigned: bool = False + +def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[str, int]: + allocation = {} + for person in people: + for os in person.preferred_operating_system: + for laptop in laptops: + if (laptop.operating_system == os and not laptop.assigned): + allocation[person.name] = laptop.id + assigned = True + break + if assigned: + break + return allocation + +people = [ + Person(name="Imran", age=22, preferred_operating_system=[OperatingSystem.UBUNTU,OperatingSystem.ARCH,OperatingSystem.MACOS]), + Person(name="Eliza", age=34, preferred_operating_system=[OperatingSystem.ARCH]), + Person(name="Maria", age=38, preferred_operating_system=[OperatingSystem.MACOS,OperatingSystem.ARCH]), +] + +laptops = [ + Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH), + Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU), + Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU), + Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS), +] + +if __name__ == "__main__": + allocation = allocate_laptops(people, laptops) + print("Allocation:", allocation) \ No newline at end of file From 176ec475ab837dc973c1f7b841a0ff9110c039f4 Mon Sep 17 00:00:00 2001 From: Emiliano Uruena Date: Wed, 25 Feb 2026 07:51:28 +0000 Subject: [PATCH 2/3] Add sadness calculator and backtracking for laptop allocation Implement calcutate_sandess and backtracking for laptop allocation based on user preferences and minimize sadness. --- laptop-allocation.py | 58 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/laptop-allocation.py b/laptop-allocation.py index d5f77b985..37ee91fd6 100644 --- a/laptop-allocation.py +++ b/laptop-allocation.py @@ -31,18 +31,52 @@ class Laptop: operating_system: OperatingSystem assigned: bool = False +# sadnes calculator +def calculate_sadness(person: Person, laptop: Laptop) -> int: + if laptop.operating_system in person.preferred_operating_system: + return person.preferred_operating_system.index(laptop.operating_system) + return 100 + def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[str, int]: - allocation = {} - for person in people: - for os in person.preferred_operating_system: - for laptop in laptops: - if (laptop.operating_system == os and not laptop.assigned): - allocation[person.name] = laptop.id - assigned = True - break - if assigned: - break - return allocation + best_allocation: Dict[str, int] = {} + min_total_sadness = float("inf") + + def backtrack(person_index: int, used_laptops: set, current_alloc: Dict[str, int], current_sadness: int): + nonlocal best_allocation, min_total_sadness + + # If all people assigned + if person_index == len(people): + if current_sadness < min_total_sadness: + min_total_sadness = current_sadness + best_allocation = current_alloc.copy() + return + + # stop if worse than best + if current_sadness >= min_total_sadness: + return + + person = people[person_index] + + for laptop in laptops: + if laptop.id not in used_laptops: + sadness = calculate_sadness(person, laptop) + + used_laptops.add(laptop.id) + current_alloc[person.name] = laptop.id + + backtrack( + person_index + 1, + used_laptops, + current_alloc, + current_sadness + sadness + ) + + # Undo choice + used_laptops.remove(laptop.id) + del current_alloc[person.name] + + backtrack(0, set(), {}, 0) + return best_allocation people = [ Person(name="Imran", age=22, preferred_operating_system=[OperatingSystem.UBUNTU,OperatingSystem.ARCH,OperatingSystem.MACOS]), @@ -59,4 +93,4 @@ def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[str, i if __name__ == "__main__": allocation = allocate_laptops(people, laptops) - print("Allocation:", allocation) \ No newline at end of file + print("Allocation:", allocation) From 1a6fb3b26676d66df41862a7f1bec7b0f7dacc5d Mon Sep 17 00:00:00 2001 From: Emiliano Uruena Date: Sun, 1 Mar 2026 22:00:37 +0000 Subject: [PATCH 3/3] Change allocation function to change the returning type of the function: Person and Laptop objects Change allocation function to change the returning type of the function: Person and Laptop objects --- laptop-allocation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/laptop-allocation.py b/laptop-allocation.py index 37ee91fd6..11ddc3a2c 100644 --- a/laptop-allocation.py +++ b/laptop-allocation.py @@ -37,11 +37,11 @@ def calculate_sadness(person: Person, laptop: Laptop) -> int: return person.preferred_operating_system.index(laptop.operating_system) return 100 -def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[str, int]: - best_allocation: Dict[str, int] = {} +def allocate_laptops(people: List[Person], laptops: List[Laptop]) -> Dict[Person, Laptop]: + best_allocation: Dict[Person, Laptop] = {} min_total_sadness = float("inf") - def backtrack(person_index: int, used_laptops: set, current_alloc: Dict[str, int], current_sadness: int): + def backtrack(person_index: int, used_laptops: set, current_alloc: Dict[Person, Laptop], current_sadness: int): nonlocal best_allocation, min_total_sadness # If all people assigned @@ -62,7 +62,7 @@ def backtrack(person_index: int, used_laptops: set, current_alloc: Dict[str, int sadness = calculate_sadness(person, laptop) used_laptops.add(laptop.id) - current_alloc[person.name] = laptop.id + current_alloc[person] = laptop backtrack( person_index + 1, @@ -73,7 +73,7 @@ def backtrack(person_index: int, used_laptops: set, current_alloc: Dict[str, int # Undo choice used_laptops.remove(laptop.id) - del current_alloc[person.name] + del current_alloc[person] backtrack(0, set(), {}, 0) return best_allocation