Last active
October 7, 2025 17:58
-
-
Save jihchi/2d993c308031cf848c404acd06bf0f8a to your computer and use it in GitHub Desktop.
Revisions
-
jihchi revised this gist
Oct 7, 2025 . 1 changed file with 58 additions and 79 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,85 +1,64 @@ const MIN = 60 * 1000; const groupChangelogEdits = ( edits: { timestamp: string; component: string }[], ) => { const map = edits.reduce<Map<string, Date[]>>( (acc, { component, timestamp }) => { if (!acc.has(component)) { acc.set(component, []); } acc.get(component)?.push(new Date(timestamp)); return acc; }, new Map(), ); for (const [_component, dates] of map) { dates.sort(); } return Array.from(map.keys()) .flatMap((component) => { const [firstDate, ...dates] = map.get(component) ?? []; const grouped = [ { component, start: firstDate, end: firstDate, }, ]; let windowEnd = new Date(firstDate.getTime() + 10 * MIN); for (const date of dates) { if (date > windowEnd) { windowEnd = new Date(date.getTime() + 10 * MIN); grouped.push({ component, start: date, end: date, }); } else { const prev = grouped[grouped.length - 1]; prev.end = new Date(Math.max(prev.end.getTime(), date.getTime())); } } return grouped; }) .map(({ component, start, end }) => ({ component, start: start.toISOString().split(".")[0] + "Z", end: end.toISOString().split(".")[0] + "Z", })); }; console.log( groupChangelogEdits([ { timestamp: "2025-10-06T08:20:00Z", component: "Header" }, { timestamp: "2025-10-06T08:05:00Z", component: "Header" }, { timestamp: "2025-10-06T08:00:00Z", component: "Header" }, { timestamp: "2025-10-06T08:15:00Z", component: "Footer" }, { timestamp: "2025-10-06T08:07:00Z", component: "Footer" }, ]), ); -
jihchi revised this gist
Oct 7, 2025 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ import { assertArrayIncludes } from "jsr:@std/assert@1.0.15"; Deno.test(function testGroupChangelogEdits() { const MIN = 60 * 1000; -
jihchi revised this gist
Oct 7, 2025 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,5 @@ Deno v2.5.3 ```sh deno run https://gist.github.com/jihchi/2d993c308031cf848c404acd06bf0f8a/raw/solve.ts ``` -
jihchi created this gist
Oct 7, 2025 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,85 @@ import { assertArrayIncludes } from "@std/assert"; Deno.test(function testGroupChangelogEdits() { const MIN = 60 * 1000; const groupChangelogEdits = ( edits: { timestamp: string; component: string }[], ) => { const map = edits.reduce<Map<string, Date[]>>( (acc, { component, timestamp }) => { if (!acc.has(component)) { acc.set(component, []); } acc.get(component)?.push(new Date(timestamp)); return acc; }, new Map(), ); for (const [_component, dates] of map) { dates.sort(); } return Array.from(map.keys()) .flatMap((component) => { const [firstDate, ...dates] = map.get(component) ?? []; const grouped = [ { component, start: firstDate, end: firstDate, }, ]; let windowEnd = new Date(firstDate.getTime() + 10 * MIN); for (const date of dates) { if (date > windowEnd) { windowEnd = new Date(date.getTime() + 10 * MIN); grouped.push({ component, start: date, end: date, }); } else { const prev = grouped[grouped.length - 1]; prev.end = new Date(Math.max(prev.end.getTime(), date.getTime())); } } return grouped; }) .map(({ component, start, end }) => ({ component, start: start.toISOString().split(".")[0] + "Z", end: end.toISOString().split(".")[0] + "Z", })); }; assertArrayIncludes( groupChangelogEdits([ { timestamp: "2025-10-06T08:20:00Z", component: "Header" }, { timestamp: "2025-10-06T08:05:00Z", component: "Header" }, { timestamp: "2025-10-06T08:00:00Z", component: "Header" }, { timestamp: "2025-10-06T08:15:00Z", component: "Footer" }, { timestamp: "2025-10-06T08:07:00Z", component: "Footer" }, ]), [ { component: "Footer", start: "2025-10-06T08:07:00Z", end: "2025-10-06T08:15:00Z", }, { component: "Header", start: "2025-10-06T08:00:00Z", end: "2025-10-06T08:05:00Z", }, { component: "Header", start: "2025-10-06T08:20:00Z", end: "2025-10-06T08:20:00Z", }, ], ); });