Provides systematic approaches for solving multi-person scheduling problems with complex constraints. This skill should be used when finding meeting times, scheduling events, or solving optimization problems involving multiple calendars, availability windows, time-based constraints, preferences, and buffer requirements.
This skill provides a systematic methodology for solving scheduling problems that involve multiple participants with individual constraints, calendar conflicts, preferences, and time-based rules. It emphasizes exhaustive search, proper constraint encoding, and rigorous verification to avoid common pitfalls.
Before attempting any search, systematically extract and classify all constraints:
1. Hard Constraints (Must be satisfied)
2. Soft Constraints (Preferences for tie-breaking)
3. Meta-Constraints
Calendar File Parsing
Constraint Documentation
Critical: Respect granularity requirements
If the task specifies "minute granularity":
Generation approach:
for each_day in date_range:
for start_minute in range(day_start, day_end - duration):
candidate = (day, start_minute, start_minute + duration)
add candidate to search space
Apply constraints in order of restrictiveness (most restrictive first):
After filtering to valid slots:
For the selected slot, explicitly verify EVERY constraint:
Selected slot: [Day], [Date], [Start]-[End]
Hard Constraint Verification:
[ ] Participant A: Start >= earliest_start ✓/✗
[ ] Participant A: End <= latest_end ✓/✗
[ ] Participant A: No calendar conflicts ✓/✗
[ ] Participant B: Start >= earliest_start ✓/✗
[ ] Participant B: Day-specific rules satisfied ✓/✗
... (continue for ALL constraints)
Soft Constraint Status:
[ ] Preference 1: satisfied/not satisfied
[ ] Preference 2: satisfied/not satisfied
Problem: Only checking hourly slots when minute granularity is specified Solution: Always check the granularity requirement and generate candidates accordingly
Problem: Truncated calendar data leading to missed conflicts Solution: Verify complete data retrieval; if truncated, parse in sections
Problem: Forgetting time-gap requirements like "15-min buffer after meetings ending at X" Solution: Include buffer constraints in the filtering phase explicitly
Problem: Treating soft constraints as hard constraints or vice versa Solution: Clearly separate preferences (tie-breakers) from requirements (filters)
Problem: Not explicitly checking each constraint for the final answer Solution: Use the verification checklist for EVERY constraint before reporting
Problem: Missing slots at exact boundary times (e.g., ending exactly at 2:00 PM when constraint is "must end by 2 PM") Solution: Clarify boundary semantics (< vs <=) and test boundary values explicitly
Problem: Jumping between days/times without systematic coverage Solution: Use programmatic exhaustive search, not manual reasoning
For complex scheduling problems, implement a programmatic solution:
# Pseudocode structure
def find_valid_slots(constraints, calendars, date_range, duration, granularity_minutes=1):
# 1. Parse all calendars
busy_times = parse_all_calendars(calendars)
# 2. Generate all candidate slots at specified granularity
candidates = generate_candidates(date_range, duration, granularity_minutes)
# 3. Filter by hard constraints
valid = []
for slot in candidates:
if satisfies_all_hard_constraints(slot, constraints, busy_times):
valid.append(slot)
# 4. Rank by preferences
valid.sort(key=lambda s: preference_score(s, constraints))
# 5. Return earliest among best-ranked
return valid[0] if valid else None
def satisfies_all_hard_constraints(slot, constraints, busy_times):
# Check EVERY hard constraint explicitly
for constraint in constraints.hard:
if not constraint.is_satisfied(slot):
return False
# Check calendar conflicts
for busy in busy_times:
if overlaps(slot, busy):
return False
return True
After finding a solution, run verification:
def verify_solution(slot, all_constraints):
print(f"Verifying: {slot}")
all_passed = True
for constraint in all_constraints:
passed = constraint.check(slot)
status = "✓" if passed else "✗"
print(f" [{status}] {constraint.description}")
if not passed:
all_passed = False
return all_passed
When presenting the solution: