11from dataclasses import dataclass
22from enum import Enum
3- from typing import List , Dict , Tuple , Optional
3+ from typing import List , Dict , Tuple
4+
45
56class OperatingSystem (Enum ):
67 MACOS = "macOS"
78 ARCH = "Arch Linux"
89 UBUNTU = "Ubuntu"
910
11+
1012@dataclass (frozen = True )
1113class Person :
1214 name : str
1315 age : int
14- # Sorted in order of preference, most preferred is first.
15- preferred_operating_systems : List [OperatingSystem ]
16+ preferred_operating_systems : Tuple [OperatingSystem ]
1617
1718
1819@dataclass (frozen = True )
1920class Laptop :
20- id : int
21+ id : str
2122 manufacturer : str
2223 model : str
2324 screen_size_in_inches : float
2425 operating_system : OperatingSystem
2526
26- def norm_os_values (value : str ) -> OperatingSystem :
27- value = value .strip ().lower ()
28- if value == "ubuntu" :
29- return OperatingSystem .UBUNTU
30- if value == "arch linux" :
31- return OperatingSystem .ARCH
32- if value == "macos" :
33- return OperatingSystem .MACOS
34- raise ValueError (f"Unknown OS: { value } " )
35-
3627
3728people = [
38- Person (name = "Imran" , age = 22 , preferred_operating_systems = [norm_os_values ("Ubuntu" ), norm_os_values ("Arch Linux" )]),
39- Person (name = "Eliza" , age = 34 , preferred_operating_systems = [norm_os_values ("Arch Linux" ), norm_os_values ("macOS" ), norm_os_values ("Ubuntu" )]),
40- Person (name = "Ira" , age = 21 , preferred_operating_systems = [norm_os_values ("Ubuntu" ), norm_os_values ("Arch Linux" )]),
41- Person (name = "Anna" , age = 34 , preferred_operating_systems = [norm_os_values ("Ubuntu" ), norm_os_values ("macOS" )]),
42- Person (name = "Nahimn" , age = 42 , preferred_operating_systems = [norm_os_values ("Ubuntu" ), norm_os_values ("Arch Linux" )])
29+ Person (
30+ name = "Imran" ,
31+ age = 22 ,
32+ preferred_operating_systems = (OperatingSystem .UBUNTU , OperatingSystem .ARCH ),
33+ ),
34+ Person (
35+ name = "Eliza" ,
36+ age = 34 ,
37+ preferred_operating_systems = (
38+ OperatingSystem .ARCH ,
39+ OperatingSystem .MACOS ,
40+ OperatingSystem .UBUNTU ,
41+ ),
42+ ),
43+ Person (
44+ name = "Ira" ,
45+ age = 21 ,
46+ preferred_operating_systems = (OperatingSystem .UBUNTU , OperatingSystem .ARCH ),
47+ ),
48+ Person (
49+ name = "Anna" ,
50+ age = 34 ,
51+ preferred_operating_systems = (OperatingSystem .UBUNTU , OperatingSystem .MACOS ),
52+ ),
53+ Person (
54+ name = "Nahimn" ,
55+ age = 42 ,
56+ preferred_operating_systems = (OperatingSystem .UBUNTU , OperatingSystem .ARCH ),
57+ ),
4358]
4459
4560laptops = [
46- Laptop (id = 1 , manufacturer = "Dell" , model = "XPS" , screen_size_in_inches = 13 , operating_system = norm_os_values ("Arch Linux" )),
47- Laptop (id = 2 , manufacturer = "Dell" , model = "XPS" , screen_size_in_inches = 15 , operating_system = norm_os_values ("Ubuntu" )),
48- Laptop (id = 3 , manufacturer = "Dell" , model = "XPS" , screen_size_in_inches = 15 , operating_system = norm_os_values ("ubuntu" )),
49- Laptop (id = 4 , manufacturer = "Apple" , model = "macBook" , screen_size_in_inches = 13 , operating_system = norm_os_values ("macOS" )),
61+ Laptop (
62+ id = 1 ,
63+ manufacturer = "Dell" ,
64+ model = "XPS" ,
65+ screen_size_in_inches = 13 ,
66+ operating_system = OperatingSystem .ARCH ,
67+ ),
68+ Laptop (
69+ id = 2 ,
70+ manufacturer = "Dell" ,
71+ model = "XPS" ,
72+ screen_size_in_inches = 15 ,
73+ operating_system = OperatingSystem .UBUNTU ,
74+ ),
75+ Laptop (
76+ id = 3 ,
77+ manufacturer = "Dell" ,
78+ model = "XPS" ,
79+ screen_size_in_inches = 15 ,
80+ operating_system = OperatingSystem .UBUNTU ,
81+ ),
82+ Laptop (
83+ id = 4 ,
84+ manufacturer = "Apple" ,
85+ model = "macBook" ,
86+ screen_size_in_inches = 13 ,
87+ operating_system = OperatingSystem .MACOS ,
88+ ),
5089]
5190
5291
53- def allocate_laptops (people : List [Person ], laptops : List [Laptop ]) -> Dict [Tuple [str , int ], int ]:
54- sadness_table : Dict [Tuple [str , int ], int ] = {}
92+ def allocate_laptops (
93+ people : List [Person ], laptops : List [Laptop ]
94+ ) -> Dict [Person , Laptop ]:
95+ allocation : Dict [Person , Laptop ] = {}
96+ available_laptops = laptops .copy ()
5597 for person in people :
56- for laptop in laptops :
98+ best_laptop = None
99+ big_sadness = 100
100+ for laptop in available_laptops :
57101 if laptop .operating_system in person .preferred_operating_systems :
58- index = person .preferred_operating_systems .index (laptop .operating_system )
59- sadness = index
102+ sadness = person .preferred_operating_systems .index (
103+ laptop .operating_system
104+ )
60105 else :
61106 sadness = 100
62- sadness_table [(person .name , laptop .id )] = sadness
63- return sadness_table
64107
108+ if sadness < big_sadness :
109+ big_sadness = sadness
110+ best_laptop = laptop
65111
66- sadness_table = allocate_laptops (people , laptops )
112+ if best_laptop is not None :
113+ allocation [person ] = best_laptop
114+ available_laptops .remove (best_laptop )
115+ return allocation
67116
68- allocation_list : List [Tuple [str , Optional [int ], int ]] = []
69- allocated_laptops : set [int ] = set ()
70- allocated_persons : set [str ] = set ()
71- total_happiness : int = 0
72117
73- for (person_name , laptop_id ), sadness in sorted (sadness_table .items (), key = lambda value : value [1 ]):
74- if laptop_id in allocated_laptops :
75- continue
76- if person_name in allocated_persons :
77- continue
78- allocation_list .append ((person_name , laptop_id , sadness ))
79- allocated_laptops .add (laptop_id )
80- allocated_persons .add (person_name )
81- total_happiness += sadness
82- print (f"{ person_name } got laptop { laptop_id } " )
118+ allocation = allocate_laptops (people , laptops )
83119
84-
85- for person in people :
86- if person .name not in allocated_persons :
87- print (f"{ person .name } did not get laptop" )
88- print (f"Total happiness: { total_happiness } " )
89-
90- print (allocation_list )
120+ for person , laptop in allocation .items ():
121+ print (f"{ person .name } - { laptop .id } " )
91122
123+ for person in people :
124+ if person not in allocation :
125+ print (f"{ person .name } did not get laptop" )
0 commit comments