from ortools.sat.python import cp_model def main() -> None: model = cp_model.CpModel() horizon = 48 # 24-hour day in 30-minute slots (adjust as needed) # Activities and durations (in 30-min increments) activities = { 'breakfast': 2, # 1 hour (prep + eat + cleanup) 'lunch': 2, 'dinner': 2, 'nap': 4, # 2-hour nap 'laundry': 4, # 2 hours 'wifes_parents': 6, # 3-hour visit 'mom': 6, # Friday night (fixed) 'personal_time': 4, # 2 hours total 'kids_duty': 1, # Rotating 30-min shifts } # --- Time Windows --- # All times are in 30-min slots from 0 (8:00 AM) to 48 (next day 8:00 AM) time_windows = { 'mom': (36, 42), # Friday 6:00 PM–9:00 PM (if Friday is day 0) 'nap': (12, 18), # Preferred nap window: 1:00 PM–4:00 PM 'laundry': (20, 36), # Flexible but avoid late-night } # --- Variables --- starts = {act: model.NewIntVar(0, horizon, f'start_{act}') for act in activities} ends = {act: model.NewIntVar(0, horizon, f'end_{act}') for act in activities} # Duration constraints for act, duration in activities.items(): model.Add(ends[act] == starts[act] + duration) # --- Fixed Time Constraints --- model.Add(starts['mom'] == time_windows['mom'][0]) # Fixed Friday night # --- Meal Spacing (4-hour gaps) --- model.Add(starts['lunch'] >= starts['breakfast'] + 8) # 8 slots = 4 hours model.Add(starts['dinner'] >= starts['lunch'] + 8) # --- Nap After Lunch --- model.Add(starts['nap'] >= starts['lunch'] + 2) # At least 1 hour after lunch # --- Laundry During Kid-Free Time --- model.Add(starts['laundry'] >= 20) # Not before 10 AM # --- Personal Time (flexible, but prioritize) --- model.AddMaxEquality(ends['personal_time'], [horizon]) # --- Kids’ Duty Constraints --- # Simplified: Alternate shifts (for realism, expand to check overlaps) for act in ['wifes_parents', 'mom', 'personal_time']: model.AddNoOverlap([starts[act], ends[act], starts['kids_duty'], ends['kids_duty']]) # --- Solve --- solver = cp_model.CpSolver() status = solver.Solve(model) # --- Print Schedule --- if status == cp_model.OPTIMAL: for act in activities: start = solver.Value(starts[act]) print(f"{act}: {start//2}:{30*(start%2):02}–{(start+activities[act])//2}:{30*((start+activities[act])%2):02}") else: print("No feasible schedule found.") if __name__ == '__main__': main()