-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c05e0f7
commit e0eb567
Showing
3 changed files
with
67 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,114 @@ | ||
|
||
import { Problem, ProblemState } from "../types"; | ||
import { IntervalVariable, Problem, ProblemState, Variable } from "../types"; | ||
import { | ||
asArray, | ||
as2dArray, | ||
asSimpleValue, | ||
asStringArray, | ||
asValueGroup, | ||
asIntervals, | ||
getIntervalBounds, | ||
} from "../utils"; | ||
|
||
interface Interval { | ||
start: number; | ||
end: number; | ||
} | ||
|
||
interface MergeIntervalsInput { | ||
intervals: Interval[]; | ||
intervals: number[][]; | ||
} | ||
|
||
export function mergeIntervals(p: MergeIntervalsInput): ProblemState[] { | ||
const { intervals } = p; | ||
const steps: ProblemState[] = []; | ||
let current = 0; | ||
|
||
// Initialize the variable for merged intervals | ||
const mergedIntervals: number[][] = []; | ||
|
||
// Helper function to create and log each step's computational state | ||
function log(point: number, intervals?: Interval[]) { | ||
function log(point: number, i?: number) { | ||
const v: Variable[] = []; | ||
const step: ProblemState = { | ||
variables: [asArray("intervals", intervals)], | ||
variables: v, | ||
breakpoint: point, | ||
}; | ||
const { min, max } = getIntervalBounds(intervals); | ||
v.push(asIntervals("intervals", intervals, [i], min, max)); | ||
v.push(asIntervals("mergedIntervals", mergedIntervals, [], min, max)); | ||
steps.push(step); | ||
} | ||
|
||
// Sort the intervals based on the start time | ||
intervals.sort((a, b) => a.start - b.start); //#1 | ||
|
||
log(1); | ||
// Sort the intervals based on the start time | ||
intervals.sort((a, b) => a[0] - b[0]); | ||
log(2); | ||
|
||
let result: Interval[] = [intervals[0]]; //#2 | ||
mergedIntervals.push(intervals[0]); | ||
|
||
for (let i = 1; i < intervals.length; i++) { | ||
const currentInterval = intervals[i]; //#3 | ||
const lastInterval = result[result.length - 1]; //#4 | ||
|
||
if (currentInterval.start <= lastInterval.end) { | ||
result[result.length - 1].end = Math.max(lastInterval.end, currentInterval.end); //#5 | ||
const currentStart = intervals[i][0]; | ||
const currentEnd = intervals[i][1]; | ||
const lastInterval = mergedIntervals[mergedIntervals.length - 1]; | ||
const lastEnd = lastInterval[1]; | ||
|
||
log(3, i); | ||
|
||
if (currentStart <= lastEnd) { | ||
lastInterval[1] = Math.max(lastEnd, currentEnd); | ||
log(4, i); | ||
} else { | ||
result.push(currentInterval); //#6 | ||
mergedIntervals.push(intervals[i]); | ||
log(5, i); | ||
} | ||
|
||
log(2, result); | ||
} | ||
|
||
log(3, result); | ||
|
||
log(6); | ||
return steps; | ||
} | ||
|
||
// Example implementation of the mergeIntervals function for demonstration and testing | ||
const code = `function mergeIntervals(intervals: Interval[]): Interval[] { | ||
//#1 Sort the intervals based on the start time | ||
intervals.sort((a, b) => a.start - b.start); | ||
const code = `function merge(intervals: number[][]): number[][] { | ||
//#1 Sort intervals by their start points | ||
intervals.sort((a, b) => a[0] - b[0]); | ||
let merged = [intervals[0]]; | ||
//#2 Initialize the result with the first interval | ||
let result = [intervals[0]]; | ||
//#3 Iterate through the intervals | ||
//#2 Start iterating through the intervals | ||
for (let i = 1; i < intervals.length; i++) { | ||
const currentInterval = intervals[i]; | ||
const lastInterval = result[result.length - 1]; | ||
//#4 Check if the current interval overlaps with the last one in the result | ||
if (currentInterval.start <= lastInterval.end) { | ||
//#5 Merge the intervals by updating the end of the last interval | ||
result[result.length - 1].end = Math.max(lastInterval.end, currentInterval.end); | ||
//#3 Check if the current interval starts before the last merged interval ends | ||
if (intervals[i][0] <= merged[merged.length - 1][1]) { | ||
//#4 If there is overlap, merge the current interval with the last one in merged | ||
merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], intervals[i][1]); | ||
} else { | ||
//#6 Add the current interval to the result | ||
result.push(currentInterval); | ||
//#5 If no overlap, add the current interval to merged | ||
merged.push(intervals[i]); | ||
} | ||
} | ||
return result; | ||
//#6 All intervals processed, return the merged intervals | ||
return merged; | ||
}`; | ||
|
||
// Description for a larger, more complex input set to test and visualize the algorithm | ||
|
||
|
||
|
||
const title = "Merge Intervals"; | ||
const getInput = () => ({ | ||
intervals: [ | ||
{ start: 1, end: 3 }, | ||
{ start: 2, end: 6 }, | ||
{ start: 8, end: 10 }, | ||
{ start: 15, end: 18 }, | ||
[21, 23], // No overlap | ||
[2, 5], // Overlaps with [1, 4] | ||
[14, 16], // No overlap | ||
[17, 20], // No overlap | ||
[8, 12], // Overlaps with [6, 10], [11, 13] | ||
[11, 13], // Overlaps with [8, 12] | ||
[22, 25], // Overlaps with [21, 23] | ||
[6, 10], // Overlaps with [8, 12] | ||
[1, 4], // Overlaps with [2, 5] | ||
], | ||
}); | ||
|
||
// Export the complete problem setup including the input function, the computational function, and other metadata | ||
export const mergeIntervalsProblem: Problem<MergeIntervalsInput, ProblemState> = { | ||
export const mergeIntervalsProblem: Problem< | ||
MergeIntervalsInput, | ||
ProblemState | ||
> = { | ||
title, | ||
code, | ||
getInput, | ||
func: mergeIntervals, | ||
id: "merge-intervals", | ||
tested: true, | ||
tags: ["interval"] | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters