{"ScriptPreparationCode":"var versionString = \u00271,3000000-2000000,2500000,3000000-3500000\u0027;\r\nvar validInputRegex = /^\\s*(\\d\u002B(-\\d\u002B)?)(,\\s*\\d\u002B(-\\d\u002B)?)*\\s*$/;","TestCases":[{"Name":"Exhaustive list of version numbers","Code":"function getVersionGaps(versions) {\r\n if (!versions || !versions.indexOf(\u0027,\u0027)) {\r\n return [];\r\n }\r\n const parsedVersions = parseVersions(versions);\r\n const gaps = [];\r\n // If the first version is greater than 1, there is a gap\r\n if (parsedVersions[0] \u003E 1) {\r\n gaps.push({ start: 1, end: parsedVersions[0] - 1 });\r\n }\r\n for (let i = 0; i \u003C parsedVersions.length - 1; i\u002B\u002B) {\r\n // If the difference between two consecutive versions is greater than 1, there is a gap\r\n if (parsedVersions[i \u002B 1] - parsedVersions[i] \u003E 1) {\r\n gaps.push({ start: parsedVersions[i] \u002B 1, end: parsedVersions[i \u002B 1] - 1 });\r\n }\r\n }\r\n return gaps;\r\n}\r\n\r\nfunction parseVersions(versions) {\r\n // Check if the input string matches any of the expected formats\r\n if (!versions || versions.trim().length == 0 || versions === \u0027undefined\u0027) {\r\n return [];\r\n }\r\n\r\n if (!versions.match(validInputRegex)) {\r\n throw new Error(\u0060Invalid input format. Expected format: \u00273\u0027 or \u00271,2,3\u0027 or \u00271-3\u0027. Received: ${versions}\u0060);\r\n\r\n }\r\n\r\n const result = [];\r\n const sections = versions.split(\u0027,\u0027);\r\n\r\n for (const section of sections) {\r\n if (section.includes(\u0027-\u0027)) {\r\n const [start, end] = section.split(\u0027-\u0027).map(Number);\r\n for (let i = start; i \u003C= end; i\u002B\u002B) {\r\n result.push(i);\r\n }\r\n } else {\r\n result.push(Number(section));\r\n }\r\n }\r\n\r\n return result;\r\n\r\n}\r\ngetVersionGaps(versionString);","IsDeferred":false},{"Name":"Handle only specified ranges","Code":"function getVersionGaps(versions) {\r\n if (!versions || !versions.trim()) return [];\r\n\r\n const parsedVersions = parseVersionString(versions);\r\n\r\n return parsedVersions.reduce((gaps, current, index, arr) =\u003E {\r\n const prevEnd = index === 0 ? 0 : arr[index - 1].end;\r\n if (current.start \u003E prevEnd \u002B 1) {\r\n gaps.push({ start: prevEnd \u002B 1, end: current.start - 1 });\r\n }\r\n return gaps;\r\n }, []);\r\n}\r\n\r\nfunction parseVersionString(versionString) {\r\n const ranges = [];\r\n if (!versionString || !versionString.trim()) {\r\n return ranges;\r\n }\r\n const parts = versionString.split(\u0027,\u0027);\r\n for (const part of parts) {\r\n if (part.includes(\u0027-\u0027)) {\r\n const [start, end] = part.split(\u0027-\u0027).map(Number);\r\n ranges.push({start, end});\r\n } else {\r\n const num = Number(part);\r\n ranges.push({start: num, end: num});\r\n }\r\n }\r\n return optimizeRanges(ranges);\r\n}\r\n\r\nfunction optimizeRanges(ranges) {\r\n return ranges\r\n .sort((a, b) =\u003E a.start - b.start)\r\n .reduce((optimized, current) =\u003E {\r\n const last = optimized[optimized.length - 1];\r\n if (!last || current.start \u003E last.end \u002B 1) {\r\n optimized.push(current);\r\n } else {\r\n last.end = Math.max(last.end, current.end);\r\n }\r\n return optimized;\r\n }, []);\r\n}\r\ngetVersionGaps(versionString);","IsDeferred":false}]}