The booking list shows two meetings back to back, but submitting them triggers a conflict warning. Elsewhere, one booking fully contains three shorter bookings, yet the statistics page reports a peak concurrency of just one. Neither bug requires starting with the UI. Extracting pure Swift interval functions on a cloud Mac, with explicit boundary rules and reference results, reduces each failure to a reproducible input. The scope here is occupancy time for a single resource—not date display or network requests.
Define the half-open interval contract first
Represent each booking as [start, end): the start is included and the end is excluded. This means [0, 10) and [10, 20) do not conflict, while [0, 10) and [9, 20) do. Ticks can represent seconds or minutes, but every calculation must use a consistent unit; do not mix different precisions directly.
Reject any input whose end is not strictly later than its start. A zero-duration reminder is not an occupancy booking and belongs in a different data model. Do not silently add a second just to make it participate in sorting.
Merging occupied intervals and finding the maximum number of simultaneous bookings are two different problems. Merging discards overlap depth, so you cannot merge first and then calculate concurrency.
If the business rules require preparation time between meetings, incorporate that time into the occupied intervals before applying the same rules. Do not add a separate check only in the UI, or the list and the submission endpoint will give different answers.
Write a standalone core implementation
Save the following as Intervals.swift. The code uses only the standard library. When merging, it joins only intervals that actually overlap; touching endpoints do not count as an overlap. Integer ticks keep the algorithm separate from date conversion at this stage.
typealias Slot = Range<Int>
func merged(_ input: [Slot]) -> [Slot] {
precondition(input.allSatisfy { !$0.isEmpty })
let sorted = input.sorted {
if $0.lowerBound == $1.lowerBound {
return $0.upperBound < $1.upperBound
}
return $0.lowerBound < $1.lowerBound
}
var result: [Slot] = []
for slot in sorted {
if let last = result.last,
slot.lowerBound < last.upperBound {
result[result.count - 1] =
last.lowerBound..<max(last.upperBound, slot.upperBound)
} else {
result.append(slot)
}
}
return result
}
func peak(_ input: [Slot]) -> Int {
precondition(input.allSatisfy { !$0.isEmpty })
let events = input.flatMap {
[(time: $0.lowerBound, delta: 1),
(time: $0.upperBound, delta: -1)]
}.sorted {
if $0.time == $1.time {
return $0.delta < $1.delta
}
return $0.time < $1.time
}
var active = 0
var maximum = 0
for event in events {
active += event.delta
maximum = max(maximum, active)
}
return maximum
}
precondition(merged([]).isEmpty)
precondition(peak([]) == 0)
precondition(merged([0..<10, 10..<20]) == [0..<10, 10..<20])
precondition(peak([0..<10, 10..<20]) == 1)
precondition(merged([0..<10, 5..<15, 10..<20]) == [0..<20])
precondition(peak([0..<10, 5..<15, 10..<20]) == 2)
precondition(merged([0..<30, 5..<10, 8..<12]) == [0..<30])
precondition(peak([0..<30, 5..<10, 8..<12]) == 3)
precondition(peak([0..<10, 0..<10]) == 2)
Run it in the terminal:
xcrun swift Intervals.swift
A successful run produces no output and exits with code zero. Using precondition rather than relying only on assert prevents the tests from becoming ineffective when assertions are disabled in a normally optimized build. The validation script must also avoid compiler options that disable safety checks.
Test simultaneous events and nested intervals
The sweep-line algorithm records a start as plus one and an end as minus one. At the same timestamp, process the decrement before the increment; otherwise, two adjacent bookings will briefly count as two simultaneous bookings. Sorting only by time without an explicit tie-breaker is a common boundary bug.
Keep at least five categories of fixed test cases: an empty list, adjacent intervals, partial overlaps, full containment, and exact duplicates. Whether duplicate intervals represent two independent bookings depends on the business input. Here, each element represents one occupancy booking, so two identical entries have a concurrency of two.
The merge algorithm has another easily missed detail: when updating the right endpoint, take the larger value. Simply replacing it with the current interval’s end can shorten the merged result when a long booking contains a short one. Unsorted input must also produce the same result; correctness cannot depend on the server happening to sort it first.
Cross-check with an independent calculation
Fixed test cases can encode the same mistaken expectations as the implementation. For integer samples over a small range, count how many intervals contain each tick to obtain an independent reference. Append the following code to the same file and run it. This is a test helper, not a replacement for the production algorithm.
func referencePeak(_ input: [Slot]) -> Int {
guard let start = input.map(\.lowerBound).min(),
let end = input.map(\.upperBound).max() else {
return 0
}
return (start..<end).map { tick in
input.filter { $0.contains(tick) }.count
}.max() ?? 0
}
let candidates: [Slot] = (0..<5).flatMap { start in
((start + 1)...5).map { start..<$0 }
}
for first in candidates {
for second in candidates {
let sample = [first, second]
precondition(peak(sample) == referencePeak(sample))
precondition(merged(sample) ==
merged(Array(sample.reversed())))
precondition(merged(merged(sample)) == merged(sample))
}
}
These checks verify concurrency correctness, independence from input order, and merge idempotence, respectively. The discrete reference algorithm applies only to the integer-tick contract used here; it does not establish coverage for arbitrary continuous time. If you add randomized tests, save failing inputs rather than recording only the random seed, so failures remain reproducible after toolchain changes.
Tighten input validation and capture failure evidence before integration
When integrating this into the application, separate parsing, normalization, and interval calculation into three layers. First obtain start and end values on the same time basis, then normalize their precision, and finally verify that the end is strictly later than the start. Precision conversion can turn a very short booking into a zero-duration interval, so validation must not happen only before conversion.
If several rooms share a booking list, group bookings by resource identifier and calculate each group separately. Meetings taking place in different rooms at the same time should not conflict with one another. If people must also be prevented from being double-booked, define a separate set of resource constraints for them rather than indiscriminately feeding every booking into a single sweep line.
For each failure, retain the resource identifier, normalized intervals, expected value, actual value, and toolchain version. Participant information is unnecessary. Before fixing the bug, add the failing input to the fixed test cases, then run the complete script. Final acceptance should require agreement across boundary cases, reference calculations, and business-level grouping—not merely the disappearance of a conflict warning in one interface.
Frequently asked questions
Do bookings conflict when one ends as the next begins?
Not under the half-open interval contract used here. Process end events before start events at the same timestamp. If setup time is required, extend the occupied intervals before checking them.
Can merged intervals tell me the peak concurrency?
No. Merging preserves occupied time but discards overlap depth. Compute peak concurrency from start and end events generated from the original intervals.
Why test with integer ticks first?
Integer ticks separate interval logic from date parsing. Production inputs still need a common time reference and precision, followed by rejection of intervals whose end is not later than their start.
Run your projects on a dedicated physical Mac
Build, test, and use a remote desktop on a cloud Mac. Choose the configuration and billing period that suit your project. Check the console for real-time availability.