def merge_overlapping(intervals):
    """Merge a list of possibly overlapping intervals.

    Args:
        intervals: list of intervals, each of which is a tuple of the
            form (start, end); start is inclusive, end is exclusive

    Returns:
        list of intervals in which overlapping ones are merged. The
        list of intervals is sorted. For example, the input
        [(1,5), (3,7), (9,12)] yields [(1,7), (9,12)]. Intervals that
        are touching (e.g., (1,3) and (3,5)) are merged into one.
    """
    if len(intervals) == 0:
        return []

    intervals = sorted(intervals)
    intervals_merged = []
    curr_start, curr_end = intervals[0][0], intervals[0][1]
    for start, end in intervals:
        if start <= curr_end:
            curr_end = max(curr_end, end)
        else:
            intervals_merged += [(curr_start, curr_end)]
            curr_start = start
            curr_end = end
    intervals_merged += [(curr_start, curr_end)]

    return intervals_merged