Skip to content

Commit

Permalink
add new interval problem
Browse files Browse the repository at this point in the history
  • Loading branch information
jaroslaw-weber committed May 18, 2024
1 parent c05e0f7 commit e0eb567
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 54 deletions.
4 changes: 3 additions & 1 deletion src/problem/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { productExceptSelfProblem } from "./list/product-of-array-except-self";
import { setMatrixZeroesProblem } from "./list/set-matrix-zeros";
import { searchProblem } from "./list/search-in-rotated-sorted-array";
import { eraseOverlapIntervalsProblem } from "./list/non-overlapping-intervals";
import { mergeIntervalsProblem } from "./list/merge-intervals";

export const problems = [
maxProfitProblem,
Expand All @@ -42,5 +43,6 @@ export const problems = [
productExceptSelfProblem,
setMatrixZeroesProblem,
searchProblem,
eraseOverlapIntervalsProblem
eraseOverlapIntervalsProblem,
mergeIntervalsProblem
].filter((x) => !x.hide);
111 changes: 61 additions & 50 deletions src/problem/list/merge-intervals.ts
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"]
};
6 changes: 3 additions & 3 deletions src/problem/list/non-overlapping-intervals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ const code = `function eraseOverlapIntervals(intervals: number[][]): number {
const title = "Non-overlapping Intervals";
const getInput = () => ({
intervals: [
[1, 3],
[17, 20],
[2, 6],
[5, 9],
[8, 10],
[12, 15],
[5, 9],
[1, 3],
[14, 18],
[17, 20],
[19, 22],
],
});
Expand Down

0 comments on commit e0eb567

Please sign in to comment.