mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 00:27:55 +00:00
Docs: Update benchmark results
This commit is contained in:
@@ -4,4 +4,6 @@ async function hashPassword(p, s) {
|
||||
const h = await scrypt(e.encode(p), e.encode(s), 1024, 8, 1, 32)
|
||||
return [...h].map(b => b.toString(16).padStart(2, '0')).join('')
|
||||
}
|
||||
export default hashPassword;
|
||||
export default hashPassword;
|
||||
// Generation time: 2.609s
|
||||
// Result: PASS
|
||||
@@ -1,9 +1,9 @@
|
||||
async function hashPassword(password, salt) {
|
||||
const { scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/+esm');
|
||||
const encoder = new TextEncoder();
|
||||
const enc = new TextEncoder();
|
||||
const hash = await scrypt(
|
||||
encoder.encode(password),
|
||||
encoder.encode(salt),
|
||||
enc.encode(password),
|
||||
enc.encode(salt),
|
||||
1024,
|
||||
8,
|
||||
1,
|
||||
@@ -11,4 +11,6 @@ async function hashPassword(password, salt) {
|
||||
);
|
||||
return Array.from(hash, b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
export default hashPassword;
|
||||
export default hashPassword;
|
||||
// Generation time: 2.743s
|
||||
// Result: PASS
|
||||
@@ -1,19 +0,0 @@
|
||||
const hashPassword = async (password, salt) => {
|
||||
const { scrypt } = await import('https://esm.sh/scrypt-js@3.0.1');
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
const hashBytes = await scrypt(
|
||||
encoder.encode(password),
|
||||
encoder.encode(salt),
|
||||
1024,
|
||||
8,
|
||||
1,
|
||||
32
|
||||
);
|
||||
|
||||
return [...hashBytes]
|
||||
.map(b => b.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
};
|
||||
export default hashPassword;
|
||||
@@ -2,6 +2,8 @@ const hashPassword = async (p, s) => {
|
||||
const { scrypt } = await import('https://esm.sh/scrypt-js')
|
||||
const e = new TextEncoder()
|
||||
const h = await scrypt(e.encode(p), e.encode(s), 1024, 8, 1, 32)
|
||||
return [...h].map(b => b.toString(16).padStart(2, '0')).join('')
|
||||
return Array.from(h).map(b => b.toString(16).padStart(2, '0')).join('')
|
||||
}
|
||||
export default hashPassword;
|
||||
export default hashPassword;
|
||||
// Generation time: 18.084s
|
||||
// Result: PASS
|
||||
@@ -1,9 +1,9 @@
|
||||
async function hashPassword(password, salt) {
|
||||
const { default: scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/index.js');
|
||||
const e = new TextEncoder();
|
||||
const p = e.encode(password);
|
||||
const s = e.encode(salt);
|
||||
const h = await scrypt(p, s, 1024, 8, 1, 32);
|
||||
return [...h].map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
const { scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/dist/scrypt.min.js');
|
||||
const enc = new TextEncoder();
|
||||
const buf = await scrypt(enc.encode(password), enc.encode(salt), 1024, 8, 1, 32);
|
||||
return Array.from(buf, b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
export default hashPassword;
|
||||
export default hashPassword;
|
||||
// Generation time: 39.100s
|
||||
// Result: FAIL
|
||||
@@ -1,7 +1,9 @@
|
||||
const e=new TextEncoder
|
||||
const hashPassword=async(p,s)=>{
|
||||
const{ scrypt }=await import('https://cdn.skypack.dev/scrypt-js')
|
||||
const {scrypt}=await import('https://cdn.skypack.dev/scrypt-js')
|
||||
const e=new TextEncoder
|
||||
const h=await scrypt(e.encode(p),e.encode(s),1024,8,1,32)
|
||||
return Array.from(h,x=>(x+256).toString(16).slice(-2)).join('')
|
||||
return [...h].map(b=>b.toString(16).padStart(2,'0')).join('')
|
||||
}
|
||||
export default hashPassword;
|
||||
export default hashPassword;
|
||||
// Generation time: 8.405s
|
||||
// Result: PASS
|
||||
@@ -1,12 +0,0 @@
|
||||
const hashPassword = async (password, salt) => {
|
||||
const { scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/scrypt.min.js')
|
||||
const encoder = new TextEncoder()
|
||||
const passwordBytes = encoder.encode(password)
|
||||
const saltBytes = encoder.encode(salt)
|
||||
|
||||
const hashBytes = await scrypt(passwordBytes, saltBytes, 1024, 8, 1, 32)
|
||||
return Array.from(hashBytes)
|
||||
.map(b => b.toString(16).padStart(2, '0'))
|
||||
.join('')
|
||||
}
|
||||
export default hashPassword;
|
||||
@@ -1,9 +0,0 @@
|
||||
async function hashPassword(password, salt) {
|
||||
const { scrypt } = await import('https://cdn.skypack.dev/scrypt-js');
|
||||
const e = new TextEncoder();
|
||||
const pw = e.encode(password);
|
||||
const s = e.encode(salt);
|
||||
const h = await scrypt(pw, s, 1024, 8, 1, 32);
|
||||
return Array.from(h).map(b=>b.toString(16).padStart(2,'0')).join('');
|
||||
}
|
||||
export default hashPassword;
|
||||
@@ -1,9 +0,0 @@
|
||||
async function hashPassword(password, salt) {
|
||||
const { scrypt } = await import('https://cdn.skypack.dev/scrypt-js');
|
||||
const encoder = new TextEncoder();
|
||||
const pwBuf = encoder.encode(password);
|
||||
const saltBuf = encoder.encode(salt);
|
||||
const hashBuf = await scrypt(pwBuf, saltBuf, 1024, 8, 1, 32);
|
||||
return Array.from(hashBuf).map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
}
|
||||
export default hashPassword;
|
||||
11
tests/10_scrypt_hash/outputs/x-ai_grok-4.js
Normal file
11
tests/10_scrypt_hash/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,11 @@
|
||||
async function hashPassword(password, salt) {
|
||||
const { scrypt } = await import('https://cdn.jsdelivr.net/npm/scrypt-js@3.0.1/index.js');
|
||||
const encoder = new TextEncoder();
|
||||
const passwordBytes = encoder.encode(password);
|
||||
const saltBytes = encoder.encode(salt);
|
||||
const hashBytes = await scrypt(passwordBytes, saltBytes, 1024, 8, 1, 32);
|
||||
return Array.from(hashBytes, byte => byte.toString(16).padStart(2, '0')).join('').toLowerCase();
|
||||
}
|
||||
export default hashPassword;
|
||||
// Generation time: 12.779s
|
||||
// Result: FAIL
|
||||
@@ -1,15 +1,12 @@
|
||||
async function analyzeGPS(readings, boundary) {
|
||||
const turf = await import('https://cdn.jsdelivr.net/npm/@turf/turf@7/+esm');
|
||||
|
||||
const turf = await import("https://esm.sh/@turf/turf");
|
||||
const valid = readings
|
||||
.filter(r => turf.booleanPointInPolygon(turf.point(r.loc), boundary, { ignoreBoundary: true }))
|
||||
.sort((a, b) => a.ts - b.ts);
|
||||
|
||||
if (valid.length < 2) return 0;
|
||||
|
||||
const line = turf.lineString(valid.map(r => r.loc));
|
||||
const len = turf.length(line, { units: 'kilometers' });
|
||||
|
||||
return Math.round(len * 100) / 100;
|
||||
return Math.round(turf.length(line, { units: "kilometers" }) * 100) / 100;
|
||||
}
|
||||
export default analyzeGPS;
|
||||
export default analyzeGPS;
|
||||
// Generation time: 3.155s
|
||||
// Result: PASS
|
||||
@@ -11,4 +11,6 @@ async function analyzeGPS(readings, boundary) {
|
||||
|
||||
return Math.round(turf.length(line) * 100) / 100;
|
||||
}
|
||||
export default analyzeGPS;
|
||||
export default analyzeGPS;
|
||||
// Generation time: 2.827s
|
||||
// Result: PASS
|
||||
@@ -1,18 +0,0 @@
|
||||
const analyzeGPS = async (readings, boundary) => {
|
||||
const { booleanPointInPolygon, lineString, length } = await import('https://cdn.jsdelivr.net/npm/@turf/turf/+esm');
|
||||
|
||||
const sortedCoords = readings
|
||||
.filter(({ loc }) => booleanPointInPolygon(loc, boundary, { ignoreBoundary: true }))
|
||||
.sort((a, b) => a.ts - b.ts)
|
||||
.map(({ loc }) => loc);
|
||||
|
||||
if (sortedCoords.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const path = lineString(sortedCoords);
|
||||
const dist = length(path, { units: 'kilometers' });
|
||||
|
||||
return Math.round(dist * 1e2) / 1e2;
|
||||
};
|
||||
export default analyzeGPS;
|
||||
@@ -1,12 +1,14 @@
|
||||
const analyzeGPS = async (readings, boundary) => {
|
||||
const turf = await import('https://cdn.jsdelivr.net/npm/@turf/turf/+esm');
|
||||
const t = await import('https://cdn.jsdelivr.net/npm/@turf/turf/+esm');
|
||||
|
||||
const pts = readings
|
||||
.filter(({ loc }) => turf.booleanPointInPolygon(turf.point(loc), boundary))
|
||||
.filter(r => t.booleanPointInPolygon(t.point(r.loc), boundary, { ignoreBoundary: true }))
|
||||
.sort((a, b) => a.ts - b.ts)
|
||||
.map(r => r.loc);
|
||||
|
||||
return pts.length < 2 ? 0 :
|
||||
+turf.length(turf.lineString(pts), { units: 'kilometers' }).toFixed(2);
|
||||
return pts.length < 2 ? 0
|
||||
: +t.length(t.lineString(pts), { units: 'kilometers' }).toFixed(2);
|
||||
};
|
||||
export default analyzeGPS;
|
||||
export default analyzeGPS;
|
||||
// Generation time: 41.986s
|
||||
// Result: PASS
|
||||
@@ -1,11 +1,18 @@
|
||||
export async function analyzeGPS(readings, boundary) {
|
||||
const { booleanPointInPolygon, lineString, length } = await import('https://cdn.skypack.dev/@turf/turf');
|
||||
async function analyzeGPS(readings, boundary) {
|
||||
const isValid = r => r?.ts != null && Array.isArray(r?.loc) && r.loc.length === 2;
|
||||
const valid = readings?.filter(isValid) || [];
|
||||
if (valid.length < 2) return 0;
|
||||
|
||||
const pts = readings
|
||||
.filter(r => booleanPointInPolygon(r.loc, boundary))
|
||||
const turf = await import('https://cdn.skypack.dev/@turf/turf').catch(() => null);
|
||||
if (!turf) return 0;
|
||||
|
||||
const points = valid
|
||||
.filter(r => turf.booleanPointInPolygon(r.loc, boundary))
|
||||
.sort((a, b) => a.ts - b.ts)
|
||||
.map(r => r.loc);
|
||||
|
||||
return pts.length < 2 ? 0 : +length(lineString(pts)).toFixed(2);
|
||||
return points.length < 2 ? 0 : Math.round(turf.length(turf.lineString(points), {units: 'kilometers'}) * 100) / 100;
|
||||
}
|
||||
export default analyzeGPS;
|
||||
export default analyzeGPS;
|
||||
// Generation time: 48.580s
|
||||
// Result: PASS
|
||||
@@ -1,13 +1,12 @@
|
||||
let turf$;
|
||||
const useTurf = () => turf$ ??= import('https://cdn.skypack.dev/@turf/turf?min');
|
||||
|
||||
async function analyzeGPS(readings, boundary) {
|
||||
const t = await useTurf();
|
||||
const pts = readings
|
||||
.filter(r => t.booleanPointInPolygon(t.point(r.loc), boundary))
|
||||
.sort((a, b) => a.ts - b.ts);
|
||||
if (pts.length < 2) return 0;
|
||||
const km = t.length(t.lineString(pts.map(r => r.loc)), { units: 'kilometers' });
|
||||
return Math.round(km * 100) / 100;
|
||||
let turfReady
|
||||
const loadTurf=()=>turfReady||(turfReady=import('https://cdn.jsdelivr.net/npm/@turf/turf@6.5.0/+esm'))
|
||||
async function analyzeGPS(readings,boundary){
|
||||
const {point,lineString,length,booleanPointInPolygon}=await loadTurf()
|
||||
const inBounds=readings.filter(r=>booleanPointInPolygon(point(r.loc),boundary,{ignoreBoundary:true})).sort((a,b)=>a.ts-b.ts)
|
||||
if(inBounds.length<2)return 0
|
||||
const km=length(lineString(inBounds.map(r=>r.loc)),{units:'kilometers'})
|
||||
return +km.toFixed(2)
|
||||
}
|
||||
export default analyzeGPS;
|
||||
export default analyzeGPS;
|
||||
// Generation time: 8.791s
|
||||
// Result: PASS
|
||||
@@ -1,16 +0,0 @@
|
||||
export const analyzeGPS = async (readings, boundary) => {
|
||||
const { default: turf } = await import('https://unpkg.com/@turf/turf@6/turf.min.js')
|
||||
|
||||
const inside = readings.filter(({ loc }) =>
|
||||
turf.booleanPointInPolygon(turf.point(loc), boundary, { ignoreBoundary: false })
|
||||
)
|
||||
|
||||
if (inside.length < 2) return 0
|
||||
|
||||
const sorted = inside.sort((a, b) => a.ts - b.ts)
|
||||
const line = turf.lineString(sorted.map(({ loc }) => loc))
|
||||
const length = turf.length(line, { units: 'kilometers' })
|
||||
|
||||
return Math.round(length * 100) / 100
|
||||
}
|
||||
export default analyzeGPS;
|
||||
@@ -1,8 +0,0 @@
|
||||
async function analyzeGPS(readings,boundary){
|
||||
const{booleanPointInPolygon,lineString,length}=await import('https://cdn.skypack.dev/@turf/turf');
|
||||
const valid=readings
|
||||
.filter(r=>booleanPointInPolygon({type:'Point',coordinates:r.loc},boundary,{ignoreBoundary:true}))
|
||||
.sort((a,b)=>a.ts-b.ts);
|
||||
return valid.length<2?0:+length(lineString(valid.map(r=>r.loc)),{units:'kilometers'}).toFixed(2);
|
||||
}
|
||||
export default analyzeGPS;
|
||||
@@ -1,6 +0,0 @@
|
||||
async function analyzeGPS(readings, boundary) {
|
||||
const { point: p, booleanPointInPolygon: i, lineString: s, length: l } = await import('https://esm.sh/@turf/turf@6');
|
||||
const v = readings.filter(r => i(p(r.loc), boundary)).sort((a, b) => a.ts - b.ts);
|
||||
return v.length < 2 ? 0 : +l(s(v.map(r => r.loc))).toFixed(2);
|
||||
}
|
||||
export default analyzeGPS;
|
||||
13
tests/11_geospatial/outputs/x-ai_grok-4.js
Normal file
13
tests/11_geospatial/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,13 @@
|
||||
async function analyzeGPS(readings, boundary) {
|
||||
const turf = await import('https://cdn.jsdelivr.net/npm/@turf/turf@6/turf.min.js');
|
||||
const valid = readings
|
||||
.filter(r => turf.booleanPointInPolygon(turf.point(r.loc), boundary))
|
||||
.sort((a, b) => a.ts - b.ts);
|
||||
if (valid.length < 2) return 0;
|
||||
const line = { type: 'LineString', coordinates: valid.map(r => r.loc) };
|
||||
const length = turf.length(line, { units: 'kilometers' });
|
||||
return Math.round(length * 100) / 100;
|
||||
}
|
||||
export default analyzeGPS;
|
||||
// Generation time: 17.976s
|
||||
// Result: FAIL
|
||||
@@ -1,12 +1,10 @@
|
||||
async function findShortestPath(graph, start, end) {
|
||||
const { default: PriorityQueue } = await import("https://esm.run/js-priority-queue");
|
||||
|
||||
const dist = {}, visited = new Set();
|
||||
|
||||
for (let n in graph) dist[n] = Infinity;
|
||||
dist[start] = 0;
|
||||
const { default: PriorityQueue } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@0.4.1/+esm');
|
||||
|
||||
const dist = { [start]: 0 };
|
||||
const visited = new Set();
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => a[1] - b[1] });
|
||||
|
||||
pq.queue([start, 0]);
|
||||
|
||||
while (pq.length) {
|
||||
@@ -17,16 +15,17 @@ async function findShortestPath(graph, start, end) {
|
||||
|
||||
if (node === end) return d;
|
||||
|
||||
for (let neighbor in graph[node] || {}) {
|
||||
if (visited.has(neighbor)) continue;
|
||||
const newDist = d + graph[node][neighbor];
|
||||
if (newDist < dist[neighbor]) {
|
||||
for (const [neighbor, weight] of Object.entries(graph[node] || {})) {
|
||||
const newDist = d + weight;
|
||||
if (newDist < (dist[neighbor] ?? Infinity)) {
|
||||
dist[neighbor] = newDist;
|
||||
pq.queue([neighbor, newDist]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dist[end] ?? Infinity;
|
||||
return Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
export default findShortestPath;
|
||||
// Generation time: 4.850s
|
||||
// Result: FAIL
|
||||
@@ -1,31 +1,35 @@
|
||||
async function findShortestPath(graph, start, end) {
|
||||
const { default: PriorityQueue } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@0.1.5/+esm');
|
||||
|
||||
const distances = Object.keys(graph).reduce((acc, node) => ({ ...acc, [node]: Infinity }), {});
|
||||
distances[start] = 0;
|
||||
const { default: PriorityQueue } = await import('https://cdn.skypack.dev/js-priority-queue');
|
||||
|
||||
const distances = {};
|
||||
const visited = new Set();
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => a.dist - b.dist });
|
||||
|
||||
for (const node in graph) distances[node] = Infinity;
|
||||
distances[start] = 0;
|
||||
pq.queue({ node: start, dist: 0 });
|
||||
|
||||
const visited = new Set();
|
||||
|
||||
while (pq.length) {
|
||||
while (pq.length > 0) {
|
||||
const { node, dist } = pq.dequeue();
|
||||
|
||||
if (visited.has(node)) continue;
|
||||
visited.add(node);
|
||||
|
||||
if (node === end) return dist;
|
||||
|
||||
for (const [neighbor, weight] of Object.entries(graph[node] || {})) {
|
||||
const newDist = dist + weight;
|
||||
if (newDist < distances[neighbor]) {
|
||||
distances[neighbor] = newDist;
|
||||
pq.queue({ node: neighbor, dist: newDist });
|
||||
visited.add(node);
|
||||
|
||||
for (const neighbor in graph[node]) {
|
||||
if (!visited.has(neighbor)) {
|
||||
const newDist = dist + graph[node][neighbor];
|
||||
if (newDist < distances[neighbor]) {
|
||||
distances[neighbor] = newDist;
|
||||
pq.queue({ node: neighbor, dist: newDist });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return distances[end];
|
||||
return Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
export default findShortestPath;
|
||||
// Generation time: 4.029s
|
||||
// Result: PASS
|
||||
@@ -1,40 +0,0 @@
|
||||
async function findShortestPath(graph, startNode, endNode) {
|
||||
const { default: PriorityQueue } = await import(
|
||||
'https://cdn.jsdelivr.net/npm/js-priority-queue@0.1.5/priority-queue.min.js'
|
||||
);
|
||||
|
||||
const distances = {};
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => a.priority - b.priority });
|
||||
|
||||
for (const node in graph) {
|
||||
distances[node] = Infinity;
|
||||
}
|
||||
distances[startNode] = 0;
|
||||
|
||||
pq.queue({ node: startNode, priority: 0 });
|
||||
|
||||
while (pq.length) {
|
||||
const { node: currentNode, priority: currentPriority } = pq.dequeue();
|
||||
|
||||
if (currentPriority > distances[currentNode]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (currentNode === endNode) {
|
||||
return currentPriority;
|
||||
}
|
||||
|
||||
for (const neighbor in graph[currentNode]) {
|
||||
const weight = graph[currentNode][neighbor];
|
||||
const newDistance = currentPriority + weight;
|
||||
|
||||
if (newDistance < distances[neighbor]) {
|
||||
distances[neighbor] = newDistance;
|
||||
pq.queue({ node: neighbor, priority: newDistance });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
@@ -1,7 +1,8 @@
|
||||
const findShortestPath = async (g, s, e) => {
|
||||
const { default: Q } = await import('https://esm.sh/js-priority-queue')
|
||||
const q = new Q({ comparator: (a, b) => a.w - b.w })
|
||||
const { default: PQ } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@0.1.5/+esm')
|
||||
const q = new PQ({ comparator: (a, b) => a.w - b.w })
|
||||
const d = { [s]: 0 }
|
||||
|
||||
q.queue({ n: s, w: 0 })
|
||||
|
||||
while (q.length) {
|
||||
@@ -9,14 +10,17 @@ const findShortestPath = async (g, s, e) => {
|
||||
if (n === e) return w
|
||||
if (w > (d[n] ?? Infinity)) continue
|
||||
|
||||
for (const v in g[n]) {
|
||||
const k = w + g[n][v]
|
||||
if (k < (d[v] ?? Infinity)) {
|
||||
d[v] = k
|
||||
q.queue({ n: v, w: k })
|
||||
for (const k in g[n] || {}) {
|
||||
const t = w + g[n][k]
|
||||
if (t < (d[k] ?? Infinity)) {
|
||||
d[k] = t
|
||||
q.queue({ n: k, w: t })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Infinity
|
||||
}
|
||||
export default findShortestPath;
|
||||
export default findShortestPath;
|
||||
// Generation time: 30.290s
|
||||
// Result: PASS
|
||||
@@ -1,28 +1,27 @@
|
||||
export async function findShortestPath(graph, start, end) {
|
||||
const { default: PriorityQueue } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@0.1.5/index.min.js');
|
||||
|
||||
if (!graph[start] || !graph[end]) return Infinity;
|
||||
if (start === end) return 0;
|
||||
|
||||
const dist = { [start]: 0 };
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => a[0] - b[0] });
|
||||
pq.queue([0, start]);
|
||||
|
||||
while (pq.length) {
|
||||
const [d, node] = pq.dequeue();
|
||||
|
||||
if (node === end) return d;
|
||||
if (d > (dist[node] ?? Infinity)) continue;
|
||||
|
||||
for (const [n, w] of Object.entries(graph[node] || {})) {
|
||||
const nd = d + w;
|
||||
if (nd < (dist[n] ?? Infinity)) {
|
||||
dist[n] = nd;
|
||||
pq.queue([nd, n]);
|
||||
let PQ;
|
||||
export async function findShortestPath(g, s, e) {
|
||||
if (!(s in g) || !(e in g)) return Infinity;
|
||||
if (!PQ) ({ default: PQ } = await import('https://cdn.skypack.dev/js-priority-queue@0.1.5'));
|
||||
const d = new Map([[s, 0]]);
|
||||
const q = new PQ({ comparator: (a, b) => a[1] - b[1] });
|
||||
const v = new Set();
|
||||
q.queue([s, 0]);
|
||||
while (q.length) {
|
||||
const [n, c] = q.dequeue();
|
||||
if (n === e) return c;
|
||||
if (v.has(n)) continue;
|
||||
v.add(n);
|
||||
if (c > (d.get(n) ?? Infinity)) continue;
|
||||
for (const [p, w] of Object.entries(g[n] || {})) {
|
||||
const t = c + w;
|
||||
if (t < (d.get(p) ?? Infinity)) {
|
||||
d.set(p, t);
|
||||
q.queue([p, t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Infinity;
|
||||
return d.get(e) ?? Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
export default findShortestPath;
|
||||
// Generation time: 95.484s
|
||||
// Result: PASS
|
||||
@@ -1,30 +1,24 @@
|
||||
let pqPromise
|
||||
const getPQ=()=>pqPromise??=import('https://cdn.jsdelivr.net/npm/js-priority-queue@latest/+esm')
|
||||
|
||||
async function findShortestPath(g,s,t){
|
||||
if(!g||!(s in g)||!(t in g)) return Infinity
|
||||
if(s===t) return 0
|
||||
const {default:PriorityQueue}=await getPQ()
|
||||
const d={[s]:0}
|
||||
const seen=new Set
|
||||
const q=new PriorityQueue({comparator:(a,b)=>a[0]-b[0]})
|
||||
q.queue([0,s])
|
||||
while(q.length){
|
||||
const [w,n]=q.dequeue()
|
||||
if(seen.has(n)) continue
|
||||
seen.add(n)
|
||||
if(n===t) return w
|
||||
const edges=g[n]
|
||||
if(!edges) continue
|
||||
for(const k in edges){
|
||||
if(seen.has(k)) continue
|
||||
const nw=w+edges[k]
|
||||
if(nw<(d[k]??Infinity)){
|
||||
d[k]=nw
|
||||
q.queue([nw,k])
|
||||
export const findShortestPath=async(g,s,e)=>{
|
||||
const{default:Q}=await import('https://esm.sh/js-priority-queue')
|
||||
const d={},v=new Set(),q=new Q({comparator:(a,b)=>a[1]-b[1]})
|
||||
for(const k in g)d[k]=Infinity
|
||||
d[s]=0
|
||||
q.queue([s,0])
|
||||
while(q.length){
|
||||
const[n,w]=q.dequeue()
|
||||
if(v.has(n))continue
|
||||
if(n===e)return w
|
||||
v.add(n)
|
||||
for(const[nb,c]of Object.entries(g[n]||{})){
|
||||
const nw=w+c
|
||||
if(nw<d[nb]){
|
||||
d[nb]=nw
|
||||
q.queue([nb,nw])
|
||||
}
|
||||
}
|
||||
}
|
||||
return Infinity
|
||||
}
|
||||
}
|
||||
}
|
||||
return Infinity
|
||||
}
|
||||
export default findShortestPath;
|
||||
export default findShortestPath;
|
||||
// Generation time: 9.436s
|
||||
// Result: PASS
|
||||
@@ -1,37 +0,0 @@
|
||||
const findShortestPath = async (graph, start, end) => {
|
||||
const { default: PriorityQueue } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@1.0.0/+esm')
|
||||
|
||||
if (!graph[start] || !graph[end]) return Infinity
|
||||
|
||||
const distances = Object.keys(graph).reduce((acc, node) => {
|
||||
acc[node] = node === start ? 0 : Infinity
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => a.distance - b.distance })
|
||||
pq.queue({ node: start, distance: 0 })
|
||||
|
||||
const visited = new Set()
|
||||
|
||||
while (pq.length) {
|
||||
const { node, distance } = pq.dequeue()
|
||||
|
||||
if (node === end) return distance
|
||||
if (visited.has(node)) continue
|
||||
|
||||
visited.add(node)
|
||||
|
||||
Object.entries(graph[node]).forEach(([neighbor, weight]) => {
|
||||
if (visited.has(neighbor)) return
|
||||
|
||||
const newDistance = distance + weight
|
||||
if (newDistance < distances[neighbor]) {
|
||||
distances[neighbor] = newDistance
|
||||
pq.queue({ node: neighbor, distance: newDistance })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return Infinity
|
||||
}
|
||||
export default findShortestPath;
|
||||
@@ -1,24 +0,0 @@
|
||||
async function findShortestPath(graph,start,end){
|
||||
const {PriorityQueue}=await import('https://cdn.skypack.dev/js-priority-queue');
|
||||
if(start===end)return 0;
|
||||
const dist={};
|
||||
dist[start]=0;
|
||||
const pq=new PriorityQueue({comparator:(a,b)=>a.dist-b.dist});
|
||||
pq.queue({node:start,dist:0});
|
||||
while(!pq.isEmpty()){
|
||||
const u=pq.dequeue();
|
||||
if(u.dist>dist[u.node])continue;
|
||||
const neighbors=graph[u.node];
|
||||
if(!neighbors)continue;
|
||||
for(const v in neighbors){
|
||||
const w=neighbors[v];
|
||||
const alt=dist[u.node]+w;
|
||||
if(alt<(dist[v]??Infinity)){
|
||||
dist[v]=alt;
|
||||
pq.queue({node:v,dist:alt});
|
||||
}
|
||||
}
|
||||
}
|
||||
return dist[end]??Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
@@ -1,21 +0,0 @@
|
||||
async function findShortestPath(graph, start, end) {
|
||||
const { PriorityQueue } = await import('https://cdn.skypack.dev/js-priority-queue');
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => a.d - b.d });
|
||||
const dist = {};
|
||||
dist[start] = 0;
|
||||
pq.queue({ node: start, d: 0 });
|
||||
while (!pq.isEmpty()) {
|
||||
const { node, d } = pq.dequeue();
|
||||
if (d > dist[node]) continue;
|
||||
if (node === end) return d;
|
||||
for (const [nei, w] of Object.entries(graph[node] || {})) {
|
||||
const alt = d + w;
|
||||
if (alt < (dist[nei] ?? Infinity)) {
|
||||
dist[nei] = alt;
|
||||
pq.queue({ node: nei, d: alt });
|
||||
}
|
||||
}
|
||||
}
|
||||
return Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
22
tests/1_dijkstra/outputs/x-ai_grok-4.js
Normal file
22
tests/1_dijkstra/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,22 @@
|
||||
async function findShortestPath(graph, start, end) {
|
||||
const PQ = (await import('https://unpkg.com/js-priority-queue@0.1.5')).default;
|
||||
const D = {};
|
||||
D[start] = 0;
|
||||
const q = new PQ({comparator: (a, b) => a.d - b.d});
|
||||
q.queue({n: start, d: 0});
|
||||
while (q.length) {
|
||||
let {n: u, d} = q.dequeue();
|
||||
if (d > D[u]) continue;
|
||||
for (let v in graph[u]) {
|
||||
let a = d + graph[u][v];
|
||||
if (a < (D[v] ?? Infinity)) {
|
||||
D[v] = a;
|
||||
q.queue({n: v, d: a});
|
||||
}
|
||||
}
|
||||
}
|
||||
return D[end] ?? Infinity;
|
||||
}
|
||||
export default findShortestPath;
|
||||
// Generation time: 82.003s
|
||||
// Result: FAIL
|
||||
@@ -1,4 +1,4 @@
|
||||
const findConvexHull = async (points) => {
|
||||
async function findConvexHull(points) {
|
||||
const _ = (await import("https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.min.js")).default;
|
||||
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
@@ -22,6 +22,11 @@ const findConvexHull = async (points) => {
|
||||
upper.push(p);
|
||||
}
|
||||
|
||||
return [...lower.slice(0, -1), ...upper.slice(0, -1)];
|
||||
};
|
||||
export default findConvexHull;
|
||||
lower.pop();
|
||||
upper.pop();
|
||||
|
||||
return [...lower, ...upper];
|
||||
}
|
||||
export default findConvexHull;
|
||||
// Generation time: 5.506s
|
||||
// Result: PASS
|
||||
@@ -1,34 +1,28 @@
|
||||
async function findConvexHull(points) {
|
||||
const { sortBy, uniqWith } = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js');
|
||||
const findConvexHull = async (points) => {
|
||||
const { sortBy, uniqWith, isEqual } = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js');
|
||||
|
||||
if (points.length < 3) return points;
|
||||
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
|
||||
const sorted = sortBy(uniqWith(points, (a, b) => a.x === b.x && a.y === b.y), ['x', 'y']);
|
||||
const sorted = sortBy(uniqWith(points, isEqual), ['x', 'y']);
|
||||
|
||||
if (sorted.length < 3) return sorted;
|
||||
|
||||
const lower = [];
|
||||
for (const p of sorted) {
|
||||
while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
|
||||
lower.pop();
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
|
||||
const buildHalf = (pts) => {
|
||||
const hull = [];
|
||||
for (const p of pts) {
|
||||
while (hull.length >= 2 && cross(hull[hull.length - 2], hull[hull.length - 1], p) <= 0) {
|
||||
hull.pop();
|
||||
}
|
||||
hull.push(p);
|
||||
}
|
||||
lower.push(p);
|
||||
}
|
||||
hull.pop();
|
||||
return hull;
|
||||
};
|
||||
|
||||
const upper = [];
|
||||
for (let i = sorted.length - 1; i >= 0; i--) {
|
||||
const p = sorted[i];
|
||||
while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
|
||||
upper.pop();
|
||||
}
|
||||
upper.push(p);
|
||||
}
|
||||
|
||||
lower.pop();
|
||||
upper.pop();
|
||||
|
||||
return lower.concat(upper);
|
||||
}
|
||||
export default findConvexHull;
|
||||
return [...buildHalf(sorted), ...buildHalf([...sorted].reverse())];
|
||||
};
|
||||
export default findConvexHull;
|
||||
// Generation time: 4.808s
|
||||
// Result: PASS
|
||||
@@ -1,29 +0,0 @@
|
||||
async const findConvexHull = async (points) => {
|
||||
const { sortBy, uniqWith, isEqual } = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.min.js');
|
||||
|
||||
const cross = (p1, p2, p3) =>
|
||||
(p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x);
|
||||
|
||||
const sortedPoints = sortBy(uniqWith(points, isEqual), ['x', 'y']);
|
||||
|
||||
if (sortedPoints.length <= 3) {
|
||||
return sortedPoints;
|
||||
}
|
||||
|
||||
const buildHull = (pointSet) => {
|
||||
const hull = [];
|
||||
for (const p of pointSet) {
|
||||
while (hull.length >= 2 && cross(hull[hull.length - 2], hull[hull.length - 1], p) <= 0) {
|
||||
hull.pop();
|
||||
}
|
||||
hull.push(p);
|
||||
}
|
||||
return hull;
|
||||
};
|
||||
|
||||
const lower = buildHull(sortedPoints);
|
||||
const upper = buildHull([...sortedPoints].reverse());
|
||||
|
||||
return [...lower.slice(0, -1), ...upper.slice(0, -1)];
|
||||
};
|
||||
export default findConvexHull;
|
||||
@@ -1,20 +1,20 @@
|
||||
const findConvexHull = async (pts) => {
|
||||
const { sortBy: S, uniqWith: U, isEqual: E } = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/+esm')
|
||||
const p = S(U(pts, E), ['x', 'y'])
|
||||
if (p.length < 3) return p
|
||||
const X = (a, b, o) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)
|
||||
const B = (list) => {
|
||||
const h = []
|
||||
for (const pt of list) {
|
||||
while (h.length >= 2 && X(h[h.length - 1], pt, h[h.length - 2]) <= 0) h.pop()
|
||||
h.push(pt)
|
||||
}
|
||||
const { default: _ } = await import('https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm')
|
||||
const s = _.sortBy(_.uniqWith(pts, _.isEqual), ['x', 'y'])
|
||||
if (s.length < 3) return s
|
||||
|
||||
const cp = (a, b, c) => (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)
|
||||
const walk = (h, p) => {
|
||||
while (h.length >= 2 && cp(h[h.length - 2], h[h.length - 1], p) <= 0) h.pop()
|
||||
h.push(p)
|
||||
return h
|
||||
}
|
||||
const l = B(p)
|
||||
const u = B(p.reverse())
|
||||
l.pop()
|
||||
u.pop()
|
||||
return l.concat(u)
|
||||
|
||||
const l = s.reduce(walk, [])
|
||||
const u = s.reduceRight(walk, [])
|
||||
|
||||
return [...l.slice(0, -1), ...u.slice(0, -1)]
|
||||
}
|
||||
export default findConvexHull;
|
||||
export default findConvexHull;
|
||||
// Generation time: 33.416s
|
||||
// Result: PASS
|
||||
@@ -1,18 +1,23 @@
|
||||
async function findConvexHull(pts) {
|
||||
if (!Array.isArray(pts)) return [];
|
||||
const { default: _ } = await import('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js');
|
||||
const points = _.sortBy(_.uniqWith(pts, (a, b) => a.x === b.x && a.y === b.y), ['x', 'y']);
|
||||
if (points.length < 3) return points;
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
const build = (h, p) => {
|
||||
while (h.length >= 2 && cross(h[h.length - 2], h[h.length - 1], p) <= 0) h.pop();
|
||||
h.push(p);
|
||||
};
|
||||
const lower = [], upper = [];
|
||||
for (const p of points) build(lower, p);
|
||||
for (let i = points.length; i--; ) build(upper, points[i]);
|
||||
lower.pop();
|
||||
upper.pop();
|
||||
return lower.concat(upper);
|
||||
async function findConvexHull(p) {
|
||||
const { default: _ } = await import('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js'),
|
||||
u = _.uniqWith(_.sortBy(p, 'x', 'y'), (a, b) => a.x === b.x && a.y === b.y);
|
||||
if (u.length < 3) return u;
|
||||
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x),
|
||||
build = (pts) => {
|
||||
const h = [];
|
||||
for (const q of pts) {
|
||||
while (h.length > 1 && cross(h[h.length - 2], h[h.length - 1], q) <= 0) h.pop();
|
||||
h.push(q);
|
||||
}
|
||||
return h;
|
||||
};
|
||||
|
||||
const l = build(u),
|
||||
r = build([...u].reverse());
|
||||
|
||||
return [...l.slice(0, -1), ...r.slice(0, -1)];
|
||||
}
|
||||
export default findConvexHull;
|
||||
export default findConvexHull;
|
||||
// Generation time: 147.393s
|
||||
// Result: FAIL
|
||||
@@ -1,19 +1,19 @@
|
||||
async function findConvexHull(points) {
|
||||
const { uniqWith, isEqual, sortBy } = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js')
|
||||
const pts = sortBy(uniqWith(points, isEqual), ['x', 'y'])
|
||||
if (pts.length < 3) return pts
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)
|
||||
const scan = (src, acc = []) => {
|
||||
src.forEach(p => {
|
||||
while (acc.length > 1 && cross(acc.at(-2), acc.at(-1), p) <= 0) acc.pop()
|
||||
acc.push(p)
|
||||
})
|
||||
return acc
|
||||
export async function findConvexHull(pts){
|
||||
const {default:_}=await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js');
|
||||
const p=_.orderBy(_.uniqWith(pts,(a,b)=>a.x===b.x&&a.y===b.y),['x','y']);
|
||||
if(p.length<3)return p;
|
||||
const c=(o,a,b)=>(a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
|
||||
const l=[],u=[];
|
||||
for(const v of p){
|
||||
while(l.length>1&&c(l[l.length-2],l[l.length-1],v)<=0)l.pop();
|
||||
l.push(v);
|
||||
}
|
||||
const lower = scan(pts)
|
||||
const upper = scan([...pts].reverse())
|
||||
lower.pop()
|
||||
upper.pop()
|
||||
return lower.concat(upper)
|
||||
for(const v of [...p].reverse()){
|
||||
while(u.length>1&&c(u[u.length-2],u[u.length-1],v)<=0)u.pop();
|
||||
u.push(v);
|
||||
}
|
||||
return l.slice(0,-1).concat(u.slice(0,-1));
|
||||
}
|
||||
export default findConvexHull;
|
||||
export default findConvexHull;
|
||||
// Generation time: 10.565s
|
||||
// Result: PASS
|
||||
@@ -1,38 +0,0 @@
|
||||
const findConvexHull = async points => {
|
||||
const { sortBy, uniqWith, isEqual } = await import('https://cdn.skypack.dev/lodash')
|
||||
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)
|
||||
|
||||
const preparePoints = pts => {
|
||||
const unique = uniqWith(pts, isEqual)
|
||||
return sortBy(unique, ['x', 'y'])
|
||||
}
|
||||
|
||||
const buildHull = pts => {
|
||||
const hull = []
|
||||
|
||||
for (const p of pts) {
|
||||
while (hull.length >= 2 && cross(hull[hull.length - 2], hull[hull.length - 1], p) <= 0) {
|
||||
hull.pop()
|
||||
}
|
||||
hull.push(p)
|
||||
}
|
||||
|
||||
const lowerHullSize = hull.length + 1
|
||||
for (let i = pts.length - 1; i >= 0; i--) {
|
||||
const p = pts[i]
|
||||
while (hull.length >= lowerHullSize && cross(hull[hull.length - 2], hull[hull.length - 1], p) <= 0) {
|
||||
hull.pop()
|
||||
}
|
||||
hull.push(p)
|
||||
}
|
||||
|
||||
hull.pop()
|
||||
return hull
|
||||
}
|
||||
|
||||
if (points.length < 3) return [...points]
|
||||
const prepared = preparePoints(points)
|
||||
return buildHull(prepared)
|
||||
}
|
||||
export default findConvexHull;
|
||||
@@ -1,12 +0,0 @@
|
||||
async function findConvexHull(pts){
|
||||
const{ sortBy:s,uniqBy:u }=await import('https://cdn.skypack.dev/lodash');
|
||||
if(!pts?.length)return[];
|
||||
const p=u(s(pts,['x','y']),t=>`${t.x},${t.y}`);
|
||||
if(p.length<2)return p;
|
||||
const c=(o,a,b)=>(a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
|
||||
let l=[];for(let t of p){while(l.length>1&&c(l[l.length-2],l[l.length-1],t)<=0)l.pop();l.push(t)}
|
||||
let r=[];for(let i=p.length-1;i>=0;i--){const t=p[i];while(r.length>1&&c(r[r.length-2],r[r.length-1],t)<=0)r.pop();r.push(t)}
|
||||
l.pop();r.pop();
|
||||
return[...l,...r];
|
||||
}
|
||||
export default findConvexHull;
|
||||
@@ -1,19 +0,0 @@
|
||||
async function findConvexHull(pts) {
|
||||
const { sortBy, uniqBy } = await import('https://cdn.skypack.dev/lodash-es');
|
||||
const ps = uniqBy(pts, p => `${p.x},${p.y}`);
|
||||
if (ps.length < 2) return ps;
|
||||
const sorted = sortBy(ps, ['x', 'y']);
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
const build = (pnts) => {
|
||||
const h = [];
|
||||
for (let p of pnts) {
|
||||
while (h.length > 1 && cross(h[h.length - 2], h.at(-1), p) <= 0) h.pop();
|
||||
h.push(p);
|
||||
}
|
||||
return h;
|
||||
};
|
||||
const lower = build(sorted);
|
||||
const upper = build([...sorted].reverse());
|
||||
return [...lower.slice(0, -1), ...upper.slice(0, -1)];
|
||||
}
|
||||
export default findConvexHull;
|
||||
28
tests/2_convex_hull/outputs/x-ai_grok-4.js
Normal file
28
tests/2_convex_hull/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,28 @@
|
||||
async function findConvexHull(points) {
|
||||
const _ = await import('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js');
|
||||
if (points.length <= 1) return points.slice();
|
||||
let pts = _.sortBy(_.uniqWith(points, (a, b) => a.x === b.x && a.y === b.y), ['x', 'y']);
|
||||
if (pts.length <= 1) return pts;
|
||||
const cross = (o, a, b) => (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
|
||||
let lower = [];
|
||||
for (let p of pts) {
|
||||
while (lower.length >= 2 && cross(lower[lower.length - 2], lower[lower.length - 1], p) <= 0) {
|
||||
lower.pop();
|
||||
}
|
||||
lower.push(p);
|
||||
}
|
||||
let upper = [];
|
||||
for (let i = pts.length - 1; i >= 0; i--) {
|
||||
let p = pts[i];
|
||||
while (upper.length >= 2 && cross(upper[upper.length - 2], upper[upper.length - 1], p) <= 0) {
|
||||
upper.pop();
|
||||
}
|
||||
upper.push(p);
|
||||
}
|
||||
lower.pop();
|
||||
upper.pop();
|
||||
return lower.concat(upper);
|
||||
}
|
||||
export default findConvexHull;
|
||||
// Generation time: 60.720s
|
||||
// Result: FAIL
|
||||
@@ -1,11 +1,13 @@
|
||||
async function findLISLength(a) {
|
||||
if (!a?.length) return 0;
|
||||
async function findLISLength(nums) {
|
||||
if (!nums?.length) return 0;
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm');
|
||||
const t = [];
|
||||
for (const n of a) {
|
||||
const i = bisectLeft(t, n);
|
||||
i < t.length ? t[i] = n : t.push(n);
|
||||
const tails = [];
|
||||
for (const n of nums) {
|
||||
const i = bisectLeft(tails, n);
|
||||
i < tails.length ? tails[i] = n : tails.push(n);
|
||||
}
|
||||
return t.length;
|
||||
return tails.length;
|
||||
}
|
||||
export default findLISLength;
|
||||
export default findLISLength;
|
||||
// Generation time: 3.101s
|
||||
// Result: PASS
|
||||
@@ -1,4 +1,4 @@
|
||||
const findLISLength = async (arr) => {
|
||||
async function findLISLength(arr) {
|
||||
const { bisectLeft } = await import('https://cdn.skypack.dev/d3-array');
|
||||
|
||||
if (!arr?.length) return 0;
|
||||
@@ -11,5 +11,7 @@ const findLISLength = async (arr) => {
|
||||
}
|
||||
|
||||
return tails.length;
|
||||
};
|
||||
export default findLISLength;
|
||||
}
|
||||
export default findLISLength;
|
||||
// Generation time: 2.177s
|
||||
// Result: PASS
|
||||
@@ -1,16 +0,0 @@
|
||||
const findLISLength = async (nums) => {
|
||||
if (!nums?.length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array/+esm');
|
||||
|
||||
const tails = [];
|
||||
|
||||
nums.forEach((num) => {
|
||||
tails[bisectLeft(tails, num)] = num;
|
||||
});
|
||||
|
||||
return tails.length;
|
||||
};
|
||||
export default findLISLength;
|
||||
@@ -1,9 +1,13 @@
|
||||
const findLISLength = async (nums) => {
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm');
|
||||
const tails = [];
|
||||
const findLISLength = async nums => {
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array/+esm')
|
||||
const tails = []
|
||||
|
||||
for (const n of nums) {
|
||||
tails[bisectLeft(tails, n)] = n;
|
||||
tails[bisectLeft(tails, n)] = n
|
||||
}
|
||||
return tails.length;
|
||||
};
|
||||
export default findLISLength;
|
||||
|
||||
return tails.length
|
||||
}
|
||||
export default findLISLength;
|
||||
// Generation time: 25.399s
|
||||
// Result: PASS
|
||||
@@ -1,14 +1,10 @@
|
||||
export async function findLISLength(nums) {
|
||||
if (!Array.isArray(nums) || nums.length === 0) return 0;
|
||||
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm');
|
||||
const tails = [];
|
||||
|
||||
for (const num of nums) {
|
||||
const idx = bisectLeft(tails, num);
|
||||
idx === tails.length ? tails.push(num) : tails[idx] = num;
|
||||
}
|
||||
|
||||
return tails.length;
|
||||
export async function findLISLength(a){
|
||||
const{bisectLeft}=await import('https://esm.sh/d3-array');
|
||||
if(!Array.isArray(a))return 0;
|
||||
const t=[];
|
||||
for(const v of a){const i=bisectLeft(t,v);i===t.length?t.push(v):t[i]=v;}
|
||||
return t.length;
|
||||
}
|
||||
export default findLISLength;
|
||||
export default findLISLength;
|
||||
// Generation time: 39.477s
|
||||
// Result: PASS
|
||||
@@ -1,10 +1,12 @@
|
||||
async function findLISLength(a) {
|
||||
const {bisectLeft} = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm')
|
||||
const t=[]
|
||||
for (const x of a||[]) {
|
||||
const i = bisectLeft(t,x)
|
||||
t[i]=x
|
||||
}
|
||||
return t.length
|
||||
async function findLISLength(a){
|
||||
const{bisectLeft}=await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm')
|
||||
const t=[]
|
||||
for(const x of a){
|
||||
const i=bisectLeft(t,x)
|
||||
t[i]=x
|
||||
}
|
||||
return t.length
|
||||
}
|
||||
export default findLISLength;
|
||||
export default findLISLength;
|
||||
// Generation time: 6.704s
|
||||
// Result: PASS
|
||||
@@ -1,14 +0,0 @@
|
||||
const findLISLength = async (nums) => {
|
||||
if (!nums.length) return 0
|
||||
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm')
|
||||
const tails = []
|
||||
|
||||
for (const num of nums) {
|
||||
const i = bisectLeft(tails, num)
|
||||
tails[i] = num
|
||||
}
|
||||
|
||||
return tails.length
|
||||
}
|
||||
export default findLISLength;
|
||||
@@ -1,2 +0,0 @@
|
||||
async function findLISLength(a){const{bisectLeft}=await import('https://cdn.skypack.dev/d3-array');let t=[];for(let n of a){let i=bisectLeft(t,n);i===t.length?t.push(n):t[i]=n}return t.length}
|
||||
export default findLISLength;
|
||||
@@ -1,11 +0,0 @@
|
||||
async function findLISLength(arr) {
|
||||
const {bisectLeft} = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm');
|
||||
let tails = [];
|
||||
for (let num of arr) {
|
||||
let i = bisectLeft(tails, num);
|
||||
if (i === tails.length) tails.push(num);
|
||||
else tails[i] = num;
|
||||
}
|
||||
return tails.length;
|
||||
}
|
||||
export default findLISLength;
|
||||
16
tests/3_lis/outputs/x-ai_grok-4.js
Normal file
16
tests/3_lis/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,16 @@
|
||||
async function findLISLength(arr) {
|
||||
const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3');
|
||||
let tails = [];
|
||||
for (let num of arr) {
|
||||
let pos = bisectLeft(tails, num);
|
||||
if (pos === tails.length) {
|
||||
tails.push(num);
|
||||
} else {
|
||||
tails[pos] = num;
|
||||
}
|
||||
}
|
||||
return tails.length;
|
||||
}
|
||||
export default findLISLength;
|
||||
// Generation time: 47.415s
|
||||
// Result: FAIL
|
||||
@@ -2,4 +2,6 @@ async function renderTemplate(template, data) {
|
||||
const { default: Handlebars } = await import('https://esm.sh/handlebars');
|
||||
return Handlebars.compile(template)(data);
|
||||
}
|
||||
export default renderTemplate;
|
||||
export default renderTemplate;
|
||||
// Generation time: 2.930s
|
||||
// Result: PASS
|
||||
@@ -1,9 +1,7 @@
|
||||
async function renderTemplate(templateString, data) {
|
||||
const { default: Handlebars } = await import(
|
||||
'https://cdn.jsdelivr.net/npm/handlebars@4.7.8/dist/handlebars.min.js'
|
||||
);
|
||||
|
||||
const template = Handlebars.compile(templateString);
|
||||
return template(data);
|
||||
async function renderTemplate(template, data) {
|
||||
const { default: Handlebars } = await import('https://cdn.jsdelivr.net/npm/handlebars@4.7.8/dist/handlebars.min.js');
|
||||
return Handlebars.compile(template)(data);
|
||||
}
|
||||
export default renderTemplate;
|
||||
export default renderTemplate;
|
||||
// Generation time: 2.224s
|
||||
// Result: FAIL
|
||||
@@ -1,5 +0,0 @@
|
||||
const renderTemplate = async (templateString, data) => {
|
||||
const { default: Handlebars } = await import('https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.min.js');
|
||||
return Handlebars.compile(templateString)(data);
|
||||
};
|
||||
export default renderTemplate;
|
||||
@@ -1,5 +1,6 @@
|
||||
const renderTemplate = async (tmpl, data) => {
|
||||
const { default: H } = await import('https://cdn.jsdelivr.net/npm/handlebars@latest/+esm')
|
||||
return H.compile(tmpl)(data)
|
||||
}
|
||||
export default renderTemplate;
|
||||
const renderTemplate = async (t, d) =>
|
||||
(await import('https://esm.sh/handlebars'))
|
||||
.default.compile(t)(d)
|
||||
export default renderTemplate;
|
||||
// Generation time: 29.656s
|
||||
// Result: PASS
|
||||
@@ -1,7 +1,12 @@
|
||||
let h, c = new Map();
|
||||
const renderTemplate = async (t, d) => {
|
||||
h ||= (await import('https://cdn.jsdelivr.net/npm/handlebars@4.7.8/dist/handlebars.min.js')).default;
|
||||
c.has(t) || c.set(t, h.compile(t));
|
||||
return c.get(t)(d);
|
||||
let hb;
|
||||
export const renderTemplate=async(t,d)=>{
|
||||
try{
|
||||
hb??=(await import('https://cdn.jsdelivr.net/npm/handlebars@4.7.8/dist/handlebars.mjs')).default;
|
||||
return hb.compile(t)(d);
|
||||
}catch(e){
|
||||
throw new Error(`Render failed: ${e.message}`);
|
||||
}
|
||||
};
|
||||
export default renderTemplate;
|
||||
export default renderTemplate;
|
||||
// Generation time: 50.722s
|
||||
// Result: FAIL
|
||||
@@ -1,5 +1,7 @@
|
||||
async function renderTemplate(t,d){
|
||||
const {default:h}=await import('https://cdn.jsdelivr.net/npm/handlebars@latest/+esm')
|
||||
return h.compile(t)(d)
|
||||
async function renderTemplate(tpl, data) {
|
||||
const { default: h } = await import('https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.esm.js')
|
||||
return h.compile(tpl)(data)
|
||||
}
|
||||
export default renderTemplate;
|
||||
export default renderTemplate;
|
||||
// Generation time: 2.868s
|
||||
// Result: FAIL
|
||||
@@ -1,6 +0,0 @@
|
||||
const renderTemplate = async (template, data) => {
|
||||
const { default: Handlebars } = await import('https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.min.js')
|
||||
const compiled = Handlebars.compile(template)
|
||||
return compiled(data)
|
||||
}
|
||||
export default renderTemplate;
|
||||
@@ -1,8 +0,0 @@
|
||||
const getHandlebars=(async()=>(await import('https://esm.sh/handlebars@4.7.8')).default)();
|
||||
|
||||
async function renderTemplate(template,data){
|
||||
const Handlebars=await getHandlebars;
|
||||
const fn=Handlebars.compile(template);
|
||||
return fn(data);
|
||||
}
|
||||
export default renderTemplate;
|
||||
8
tests/4_transpiler/outputs/x-ai_grok-4.js
Normal file
8
tests/4_transpiler/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,8 @@
|
||||
async function renderTemplate(template, data) {
|
||||
const { default: Handlebars } = await import('https://esm.sh/handlebars');
|
||||
const compiled = Handlebars.compile(template);
|
||||
return compiled(data);
|
||||
}
|
||||
export default renderTemplate;
|
||||
// Generation time: 22.419s
|
||||
// Result: PASS
|
||||
@@ -1,5 +1,7 @@
|
||||
async function parseMarkdown(t) {
|
||||
const { marked } = await import("https://esm.sh/marked@12.0.0");
|
||||
return marked.parse(t);
|
||||
async function parseMarkdown(md) {
|
||||
const { marked } = await import('https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js');
|
||||
return marked.parse(md);
|
||||
}
|
||||
export default parseMarkdown;
|
||||
export default parseMarkdown;
|
||||
// Generation time: 2.905s
|
||||
// Result: PASS
|
||||
@@ -2,4 +2,6 @@ async function parseMarkdown(md) {
|
||||
const { marked } = await import('https://cdn.jsdelivr.net/npm/marked@11.1.1/+esm');
|
||||
return marked.parse(md);
|
||||
}
|
||||
export default parseMarkdown;
|
||||
export default parseMarkdown;
|
||||
// Generation time: 1.766s
|
||||
// Result: PASS
|
||||
@@ -1,24 +0,0 @@
|
||||
const parseMarkdown = async (md) => {
|
||||
try {
|
||||
const [
|
||||
{ marked },
|
||||
{ default: DOMPurify }
|
||||
] = await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/marked@13.0.0/lib/marked.esm.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/dompurify@3.1.5/dist/purify.es.mjs')
|
||||
]);
|
||||
|
||||
const rawHtml = marked.parse(md || '', {
|
||||
gfm: true,
|
||||
breaks: true,
|
||||
});
|
||||
|
||||
return DOMPurify.sanitize(rawHtml);
|
||||
} catch (err) {
|
||||
console.error('Failed to parse markdown:', err);
|
||||
const el = document.createElement('div');
|
||||
el.textContent = md || '';
|
||||
return el.innerHTML;
|
||||
}
|
||||
};
|
||||
export default parseMarkdown;
|
||||
@@ -1,5 +1,7 @@
|
||||
const parseMarkdown = async text => {
|
||||
const { parse } = await import('https://esm.sh/marked')
|
||||
return parse(text)
|
||||
const parseMarkdown = async (md) => {
|
||||
const { parse } = await import('https://esm.sh/marked@12.0.0')
|
||||
return parse(String(md || ''))
|
||||
}
|
||||
export default parseMarkdown;
|
||||
export default parseMarkdown;
|
||||
// Generation time: 42.618s
|
||||
// Result: PASS
|
||||
@@ -1,15 +1,13 @@
|
||||
async function parseMarkdown(md) {
|
||||
if (!md?.trim()) return '';
|
||||
try {
|
||||
const [{ marked }, { default: DOMPurify }] = await Promise.all([
|
||||
import('https://esm.sh/marked@9'),
|
||||
import('https://esm.sh/dompurify@3')
|
||||
]);
|
||||
marked.setOptions({ gfm: true, breaks: true });
|
||||
return DOMPurify.sanitize(marked.parse(md));
|
||||
} catch (e) {
|
||||
console.error('Markdown parse error:', e);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
export default parseMarkdown;
|
||||
let p;
|
||||
|
||||
export const parseMarkdown = async (s) => {
|
||||
p ||= Promise.all([
|
||||
import('https://esm.sh/marked@7.0.4').then(r => r.marked),
|
||||
import('https://esm.sh/dompurify@3.0.5').then(r => r.default)
|
||||
]);
|
||||
const [m, d] = await p;
|
||||
return d.sanitize(m.parse(s));
|
||||
};
|
||||
export default parseMarkdown;
|
||||
// Generation time: 550.549s
|
||||
// Result: PASS
|
||||
@@ -1,12 +1,17 @@
|
||||
const parseMarkdown=(()=>{
|
||||
let m,r
|
||||
return async t=>{
|
||||
if(!r){
|
||||
({marked:m}=await import('https://cdn.jsdelivr.net/npm/marked@11.1.1/+esm'))
|
||||
m.setOptions({gfm:1,mangle:0,headerIds:0})
|
||||
r=1
|
||||
}
|
||||
return m.parse(t)
|
||||
}
|
||||
})()
|
||||
export default parseMarkdown;
|
||||
const loadLibs=(()=>{let cache;return async()=>cache||(cache=Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/marked@11.1.0/lib/marked.esm.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/dompurify@3.0.6/dist/purify.es.mjs')
|
||||
]).then(([{marked},purifyMod])=>{
|
||||
const purify=(purifyMod.default||purifyMod)(window);
|
||||
marked.setOptions({gfm:true,headerIds:true,mangle:false});
|
||||
return {marked,purify};
|
||||
}));})();
|
||||
|
||||
const parseMarkdown=async input=>{
|
||||
const {marked,purify}=await loadLibs();
|
||||
const html=marked.parse(typeof input==='string'?input:`${input??''}`);
|
||||
return purify.sanitize(html,{USE_PROFILES:{html:true}});
|
||||
};
|
||||
export default parseMarkdown;
|
||||
// Generation time: 15.618s
|
||||
// Result: FAIL
|
||||
@@ -1,15 +0,0 @@
|
||||
const parseMarkdown = async (markdown) => {
|
||||
const { default: marked } = await import('https://cdn.jsdelivr.net/npm/marked@4.0.12/lib/marked.esm.js')
|
||||
const { default: DOMPurify } = await import('https://cdn.jsdelivr.net/npm/dompurify@3.0.5/dist/purify.es.mjs')
|
||||
|
||||
marked.setOptions({
|
||||
gfm: true,
|
||||
breaks: true,
|
||||
headerIds: false,
|
||||
mangle: false
|
||||
})
|
||||
|
||||
const html = marked.parse(markdown)
|
||||
return DOMPurify.sanitize(html)
|
||||
}
|
||||
export default parseMarkdown;
|
||||
@@ -1,6 +0,0 @@
|
||||
async function parseMarkdown(md){
|
||||
const{marked}=await import('https://esm.sh/marked');
|
||||
const{DOMPurify}=await import('https://esm.sh/dompurify');
|
||||
return DOMPurify.sanitize(marked.parse(md));
|
||||
}
|
||||
export default parseMarkdown;
|
||||
@@ -1,5 +0,0 @@
|
||||
async function parseMarkdown(md) {
|
||||
const { marked } = await import('https://cdn.skypack.dev/marked');
|
||||
return marked.parse(md);
|
||||
}
|
||||
export default parseMarkdown;
|
||||
7
tests/5_markdown_parser/outputs/x-ai_grok-4.js
Normal file
7
tests/5_markdown_parser/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,7 @@
|
||||
async function parseMarkdown(markdown) {
|
||||
const { marked } = await import('https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js');
|
||||
return marked(markdown);
|
||||
}
|
||||
export default parseMarkdown;
|
||||
// Generation time: 16.386s
|
||||
// Result: PASS
|
||||
@@ -1,32 +1,24 @@
|
||||
async function processCSV(csv, config) {
|
||||
const { parse } = await import('https://cdn.jsdelivr.net/npm/papaparse@5/+esm');
|
||||
const { filterColumn, filterValue, groupBy, aggregateColumn, operation } = config;
|
||||
|
||||
const { default: Papa } = await import('https://cdn.jsdelivr.net/npm/papaparse@5/+esm');
|
||||
|
||||
const { data } = Papa.parse(csv, { header: true, skipEmptyLines: true });
|
||||
const { data } = parse(csv, { header: true, skipEmptyLines: true });
|
||||
|
||||
const filtered = data.filter(row => row[filterColumn] == filterValue);
|
||||
|
||||
const groups = {};
|
||||
for (const row of filtered) {
|
||||
const key = row[groupBy];
|
||||
(groups[key] ??= []).push(row);
|
||||
(groups[key] ??= []).push(+row[aggregateColumn] || 0);
|
||||
}
|
||||
|
||||
const toNum = v => {
|
||||
const n = Number(v);
|
||||
return isNaN(n) ? 0 : n;
|
||||
};
|
||||
|
||||
const ops = {
|
||||
sum: rows => rows.reduce((s, r) => s + toNum(r[aggregateColumn]), 0),
|
||||
avg: rows => rows.length ? ops.sum(rows) / rows.length : 0,
|
||||
count: rows => rows.length
|
||||
};
|
||||
|
||||
return Object.entries(groups).map(([k, v]) => ({
|
||||
[groupBy]: k,
|
||||
result: ops[operation](v)
|
||||
return Object.entries(groups).map(([key, vals]) => ({
|
||||
[groupBy]: key,
|
||||
result: operation === 'count' ? vals.length :
|
||||
operation === 'sum' ? vals.reduce((a, b) => a + b, 0) :
|
||||
vals.reduce((a, b) => a + b, 0) / vals.length
|
||||
}));
|
||||
}
|
||||
export default processCSV;
|
||||
export default processCSV;
|
||||
// Generation time: 4.406s
|
||||
// Result: FAIL
|
||||
@@ -1,27 +1,28 @@
|
||||
const processCSV = async (csv, { filterColumn, filterValue, groupBy, aggregateColumn, operation }) => {
|
||||
const [{ default: Papa }] = await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm')
|
||||
]);
|
||||
|
||||
const { data } = Papa.parse(csv, { header: true, skipEmptyLines: true });
|
||||
async function processCSV(csv, config) {
|
||||
const { parse } = await import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm');
|
||||
|
||||
const filtered = data.filter(row => row[filterColumn] == filterValue);
|
||||
const { data } = parse(csv, { header: true, skipEmptyLines: true });
|
||||
|
||||
const filtered = data.filter(row => row[config.filterColumn] == config.filterValue);
|
||||
|
||||
const groups = filtered.reduce((acc, row) => {
|
||||
const key = row[groupBy];
|
||||
if (!acc[key]) acc[key] = [];
|
||||
acc[key].push(row);
|
||||
const key = row[config.groupBy];
|
||||
(acc[key] ??= []).push(row);
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
|
||||
return Object.entries(groups).map(([key, rows]) => {
|
||||
const values = rows.map(r => Number(r[aggregateColumn]) || 0);
|
||||
const values = rows.map(r => Number(r[config.aggregateColumn]) || 0);
|
||||
const sum = values.reduce((a, b) => a + b, 0);
|
||||
|
||||
return {
|
||||
[groupBy]: key,
|
||||
result: operation === 'sum' ? sum : operation === 'avg' ? sum / values.length : values.length
|
||||
[config.groupBy]: key,
|
||||
result: config.operation === 'sum' ? sum :
|
||||
config.operation === 'avg' ? sum / values.length :
|
||||
values.length
|
||||
};
|
||||
});
|
||||
};
|
||||
export default processCSV;
|
||||
}
|
||||
export default processCSV;
|
||||
// Generation time: 4.238s
|
||||
// Result: FAIL
|
||||
@@ -1,34 +0,0 @@
|
||||
async function processCSV(csvString, config) {
|
||||
const {
|
||||
filterColumn: fc,
|
||||
filterValue: fv,
|
||||
groupBy: gb,
|
||||
aggregateColumn: ac,
|
||||
operation: op
|
||||
} = config;
|
||||
|
||||
const { default: Papa } = await import('https://cdn.jsdelivr.net/npm/papaparse@5.3.2/papaparse.min.js');
|
||||
|
||||
const { data } = Papa.parse(csvString, {
|
||||
header: true,
|
||||
skipEmptyLines: true
|
||||
});
|
||||
|
||||
const groups = data.reduce((acc, row) => {
|
||||
if (row[fc] == fv) {
|
||||
const key = row[gb];
|
||||
const val = Number(row[ac]) || 0;
|
||||
|
||||
acc[key] = acc[key] || { sum: 0, count: 0 };
|
||||
acc[key].sum += val;
|
||||
acc[key].count++;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return Object.entries(groups).map(([key, { sum, count }]) => ({
|
||||
[gb]: key,
|
||||
result: op === 'avg' ? sum / count : op === 'sum' ? sum : count,
|
||||
}));
|
||||
}
|
||||
export default processCSV;
|
||||
@@ -1,19 +1,16 @@
|
||||
export const processCSV = async (csvString, { filterColumn, filterValue, groupBy, aggregateColumn, operation }) => {
|
||||
const [{ csvParse }, { rollup, sum, mean }] = await Promise.all([
|
||||
import('https://esm.sh/d3-dsv'),
|
||||
import('https://esm.sh/d3-array')
|
||||
]);
|
||||
|
||||
const getValue = d => +(d[aggregateColumn]) || 0;
|
||||
|
||||
const grouped = rollup(
|
||||
csvParse(csvString).filter(row => row[filterColumn] == filterValue),
|
||||
group => operation === 'count'
|
||||
? group.length
|
||||
: (operation === 'sum' ? sum : mean)(group, getValue),
|
||||
row => row[groupBy]
|
||||
);
|
||||
|
||||
return Array.from(grouped, ([key, result]) => ({ [groupBy]: key, result }));
|
||||
const processCSV = async (str, { filterColumn: fc, filterValue: fv, groupBy: gb, aggregateColumn: ac, operation: op }) => {
|
||||
const { csvParse, rollups, sum } = await import('https://esm.sh/d3@7');
|
||||
const num = v => +v || 0;
|
||||
return rollups(
|
||||
csvParse(str).filter(d => d[fc] == fv),
|
||||
g => {
|
||||
if (op === 'count') return g.length;
|
||||
const t = sum(g, d => num(d[ac]));
|
||||
return op === 'sum' ? t : t / g.length;
|
||||
},
|
||||
d => d[gb]
|
||||
).map(([k, v]) => ({ [gb]: k, result: v }));
|
||||
};
|
||||
export default processCSV;
|
||||
export default processCSV;
|
||||
// Generation time: 40.784s
|
||||
// Result: PASS
|
||||
@@ -1,2 +1,17 @@
|
||||
async function processCSV(csv,{filterColumn:f,filterValue:v,groupBy:g,aggregateColumn:a,operation:o}){const{default:P}=await import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm');const{data}=P.parse(csv,{header:true});const grouped=data.filter(r=>r[f]==v).reduce((c,r)=>{const k=r[g],n=Number(r[a])||0;c[k]||=(c[k]={s:0,c:0});c[k].s+=n;c[k].c++;return c},{});return Object.entries(grouped).map(([k,{s,c}])=>({[g]:k,result:o=='sum'?s:o=='avg'?s/c:c}))}
|
||||
export default processCSV;
|
||||
async function processCSV(csv, { filterColumn: fc, filterValue: fv, groupBy: gb, aggregateColumn: ac, operation: op }) {
|
||||
const { default: Papa } = await import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm');
|
||||
const groups = {};
|
||||
|
||||
Papa.parse(csv, { header: true }).data
|
||||
.filter(r => r[fc] == fv)
|
||||
.forEach(r => {
|
||||
const key = r[gb], g = groups[key] || (groups[key] = { c: 0, s: 0 });
|
||||
g.c++;
|
||||
g.s += +r[ac] || 0;
|
||||
});
|
||||
|
||||
return Object.entries(groups).map(([k, { c, s }]) => ({ [gb]: k, result: op === 'count' ? c : op === 'avg' ? s / c : s }));
|
||||
}
|
||||
export default processCSV;
|
||||
// Generation time: 66.769s
|
||||
// Result: PASS
|
||||
@@ -1,21 +1,16 @@
|
||||
const libCache={},load=u=>libCache[u]??=import(u);
|
||||
const store={},load=u=>store[u]??=import(u),csvLib='https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm',dataLib='https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/+esm',toNum=v=>{const n=Number(v);return Number.isFinite(n)?n:0};
|
||||
|
||||
async function processCSV(csv,cfg){
|
||||
const [{csvParse},{groupBy}]=await Promise.all([
|
||||
load('https://cdn.jsdelivr.net/npm/d3-dsv@3.0.1/+esm'),
|
||||
load('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/+esm')
|
||||
]);
|
||||
const {filterColumn:f,filterValue:v,groupBy:k,aggregateColumn:a,operation:o}=cfg;
|
||||
const rows=csvParse(csv).filter(r=>r[f]==v);
|
||||
const grouped=groupBy(rows,r=>r[k]);
|
||||
return Object.entries(grouped).map(([g,list])=>{
|
||||
const nums=list.map(r=>{
|
||||
const n=+r[a];
|
||||
return Number.isFinite(n)?n:0;
|
||||
});
|
||||
const sum=nums.reduce((s,n)=>s+n,0);
|
||||
const result=o==='count'?list.length:o==='sum'?sum:list.length?sum/list.length:0;
|
||||
return {[k]:g,result};
|
||||
async function processCSV(csv,opt){
|
||||
const [{Papa},{groupBy:gb}] = await Promise.all([load(csvLib),load(dataLib)]);
|
||||
const {filterColumn:f,filterValue:v,groupBy:g,aggregateColumn:a,operation:o}=opt;
|
||||
const rows=Papa.parse(csv,{header:true,skipEmptyLines:true}).data.filter(r=>r&&r[f]==v);
|
||||
const grouped=gb(rows,r=>r[g]);
|
||||
return Object.entries(grouped).map(([k,items])=>{
|
||||
const total=items.reduce((s,r)=>s+toNum(r[a]),0);
|
||||
const result=o==='count'?items.length:o==='sum'?total:items.length?total/items.length:0;
|
||||
return {[g]:k,result};
|
||||
});
|
||||
}
|
||||
export default processCSV;
|
||||
export default processCSV;
|
||||
// Generation time: 29.916s
|
||||
// Result: FAIL
|
||||
@@ -1,25 +0,0 @@
|
||||
const processCSV = async (csvData, config) => {
|
||||
const { parse } = await import('https://cdn.skypack.dev/papaparse@5.3.0')
|
||||
const { filterColumn, filterValue, groupBy, aggregateColumn, operation } = config
|
||||
const { data } = parse(csvData, { header: true })
|
||||
|
||||
const filtered = data.filter(row => row[filterColumn] == filterValue)
|
||||
const groups = filtered.reduce((acc, row) => {
|
||||
const key = row[groupBy]
|
||||
if (!acc[key]) acc[key] = []
|
||||
acc[key].push(row)
|
||||
return acc
|
||||
}, {})
|
||||
|
||||
return Object.entries(groups).map(([groupValue, rows]) => {
|
||||
const numbers = rows.map(row => +row[aggregateColumn] || 0)
|
||||
let result
|
||||
|
||||
if (operation === 'sum') result = numbers.reduce((a, b) => a + b, 0)
|
||||
if (operation === 'avg') result = numbers.reduce((a, b) => a + b, 0) / numbers.length
|
||||
if (operation === 'count') result = numbers.length
|
||||
|
||||
return { [groupBy]: groupValue, result }
|
||||
})
|
||||
}
|
||||
export default processCSV;
|
||||
@@ -1,17 +0,0 @@
|
||||
async function processCSV(csv,config){
|
||||
const Papa=(await import('https://cdn.skypack.dev/papaparse')).default;
|
||||
const parsed=Papa.parse(csv,{header:!0}).data;
|
||||
const{filterColumn:fc,filterValue:fv,groupBy:gb,aggregateColumn:ac,operation:op}=config;
|
||||
const filtered=parsed.filter(r=>r[fc]==fv);
|
||||
const groups=new Map;
|
||||
for(const r of filtered){
|
||||
const gv=r[gb];
|
||||
const v=Number(r[ac])||0;
|
||||
const g=groups.get(gv)||{sum:0,count:0};
|
||||
g.sum+=v;
|
||||
g.count++;
|
||||
groups.set(gv,g);
|
||||
}
|
||||
return Array.from(groups,(g,gv)=>(({[gb]:gv,result:op==='sum'?g.sum:op==='count'?g.count:g.sum/g.count})));
|
||||
}
|
||||
export default processCSV;
|
||||
@@ -1,15 +0,0 @@
|
||||
async function processCSV(csv, config) {
|
||||
const [{ default: Papa }, { aq, sum, mean, count }] = await Promise.all([
|
||||
import('https://cdn.skypack.dev/papaparse'),
|
||||
import('https://cdn.skypack.dev/arquero')
|
||||
]);
|
||||
const data = Papa.parse(csv, { header: true, skipEmptyLines: true }).data;
|
||||
const { filterColumn, filterValue, groupBy, aggregateColumn, operation } = config;
|
||||
let table = aq.from(data).filter(d => d[filterColumn] == filterValue);
|
||||
if (operation !== 'count') {
|
||||
table = table.derive({ [aggregateColumn]: d => Number(d[aggregateColumn]) || 0 });
|
||||
}
|
||||
const makeAgg = operation === 'count' ? count() : { sum: sum, avg: mean }[operation](aggregateColumn);
|
||||
return table.groupby(groupBy).rollup({ result: makeAgg }).objects();
|
||||
}
|
||||
export default processCSV;
|
||||
20
tests/6_csv_processor/outputs/x-ai_grok-4.js
Normal file
20
tests/6_csv_processor/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,20 @@
|
||||
async function processCSV(csvString, config) {
|
||||
const d3 = await import('https://unpkg.com/d3?module');
|
||||
const data = d3.csvParse(csvString);
|
||||
const filtered = data.filter(row => row[config.filterColumn] == config.filterValue);
|
||||
const grouped = d3.group(filtered, d => d[config.groupBy]);
|
||||
return [...grouped].map(([key, group]) => {
|
||||
const col = config.aggregateColumn;
|
||||
const vals = group.map(r => Number(r[col]) || 0);
|
||||
let result;
|
||||
switch (config.operation) {
|
||||
case 'sum': result = vals.reduce((a, b) => a + b, 0); break;
|
||||
case 'avg': result = vals.reduce((a, b) => a + b, 0) / vals.length; break;
|
||||
case 'count': result = group.length; break;
|
||||
}
|
||||
return { [config.groupBy]: key, result };
|
||||
});
|
||||
}
|
||||
export default processCSV;
|
||||
// Generation time: 34.010s
|
||||
// Result: PASS
|
||||
@@ -7,71 +7,70 @@ async function findAvailableSlots(calendar1, calendar2, constraints) {
|
||||
const [whStartH, whStartM] = workHours.start.split(':').map(Number);
|
||||
const [whEndH, whEndM] = workHours.end.split(':').map(Number);
|
||||
|
||||
const busyIntervals = [...calendar1, ...calendar2]
|
||||
.map(b => Interval.fromDateTimes(
|
||||
DateTime.fromISO(b.start, { zone: 'utc' }),
|
||||
DateTime.fromISO(b.end, { zone: 'utc' })
|
||||
))
|
||||
.filter(i => i.isValid)
|
||||
const allBusy = [...calendar1, ...calendar2]
|
||||
.map(b => ({
|
||||
start: DateTime.fromISO(b.start, { zone: 'utc' }),
|
||||
end: DateTime.fromISO(b.end, { zone: 'utc' })
|
||||
}))
|
||||
.filter(b => b.end > rangeStart && b.start < rangeEnd)
|
||||
.sort((a, b) => a.start - b.start);
|
||||
|
||||
const merged = [];
|
||||
for (const interval of busyIntervals) {
|
||||
if (!merged.length || merged[merged.length - 1].end < interval.start) {
|
||||
merged.push(interval);
|
||||
for (const b of allBusy) {
|
||||
if (!merged.length || b.start > merged[merged.length - 1].end) {
|
||||
merged.push({ start: b.start, end: b.end });
|
||||
} else {
|
||||
const last = merged.pop();
|
||||
merged.push(Interval.fromDateTimes(
|
||||
last.start,
|
||||
last.end > interval.end ? last.end : interval.end
|
||||
));
|
||||
merged[merged.length - 1].end = DateTime.max(merged[merged.length - 1].end, b.end);
|
||||
}
|
||||
}
|
||||
|
||||
const freeIntervals = [];
|
||||
const free = [];
|
||||
let cursor = rangeStart;
|
||||
for (const busy of merged) {
|
||||
if (busy.start > cursor && busy.start <= rangeEnd) {
|
||||
freeIntervals.push(Interval.fromDateTimes(cursor, busy.start < rangeEnd ? busy.start : rangeEnd));
|
||||
for (const b of merged) {
|
||||
if (b.start > cursor) {
|
||||
free.push({ start: cursor, end: b.start });
|
||||
}
|
||||
cursor = busy.end > cursor ? busy.end : cursor;
|
||||
cursor = DateTime.max(cursor, b.end);
|
||||
}
|
||||
if (cursor < rangeEnd) {
|
||||
freeIntervals.push(Interval.fromDateTimes(cursor, rangeEnd));
|
||||
free.push({ start: cursor, end: rangeEnd });
|
||||
}
|
||||
|
||||
const getWorkInterval = day => {
|
||||
const start = day.set({ hour: whStartH, minute: whStartM, second: 0, millisecond: 0 });
|
||||
const end = day.set({ hour: whEndH, minute: whEndM, second: 0, millisecond: 0 });
|
||||
return start < end ? Interval.fromDateTimes(start, end) : null;
|
||||
const getWorkWindow = (day) => {
|
||||
const ws = day.set({ hour: whStartH, minute: whStartM, second: 0, millisecond: 0 });
|
||||
const we = day.set({ hour: whEndH, minute: whEndM, second: 0, millisecond: 0 });
|
||||
return { start: ws, end: we };
|
||||
};
|
||||
|
||||
const slots = [];
|
||||
|
||||
for (const free of freeIntervals) {
|
||||
let day = free.start.startOf('day');
|
||||
const endDay = free.end.startOf('day');
|
||||
for (const f of free) {
|
||||
let day = f.start.startOf('day');
|
||||
const lastDay = f.end.startOf('day');
|
||||
|
||||
while (day <= endDay) {
|
||||
const workInt = getWorkInterval(day);
|
||||
if (workInt) {
|
||||
const intersection = free.intersection(workInt);
|
||||
if (intersection && intersection.length('minutes') >= durationMinutes) {
|
||||
let slotStart = intersection.start;
|
||||
while (slotStart.plus({ minutes: durationMinutes }) <= intersection.end) {
|
||||
const slotEnd = slotStart.plus({ minutes: durationMinutes });
|
||||
slots.push({
|
||||
start: slotStart.toISO({ suppressMilliseconds: true }),
|
||||
end: slotEnd.toISO({ suppressMilliseconds: true })
|
||||
});
|
||||
slotStart = slotEnd;
|
||||
}
|
||||
while (day <= lastDay) {
|
||||
const ww = getWorkWindow(day);
|
||||
const effStart = DateTime.max(f.start, ww.start, rangeStart);
|
||||
const effEnd = DateTime.min(f.end, ww.end, rangeEnd);
|
||||
|
||||
if (effStart < effEnd) {
|
||||
let slotStart = effStart;
|
||||
while (true) {
|
||||
const slotEnd = slotStart.plus({ minutes: durationMinutes });
|
||||
if (slotEnd > effEnd) break;
|
||||
slots.push({
|
||||
start: slotStart.toISO(),
|
||||
end: slotEnd.toISO()
|
||||
});
|
||||
slotStart = slotEnd;
|
||||
}
|
||||
}
|
||||
day = day.plus({ days: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
return slots.sort((a, b) => a.start.localeCompare(b.start));
|
||||
return slots;
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
export default findAvailableSlots;
|
||||
// Generation time: 12.726s
|
||||
// Result: PASS
|
||||
@@ -1,69 +1,103 @@
|
||||
const findAvailableSlots = async (calendar1, calendar2, constraints) => {
|
||||
const { startOfDay, addMinutes, parseISO, formatISO } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.0.0/+esm');
|
||||
const { parseISO, addMinutes, isWithinInterval, isBefore, isAfter, isEqual } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.0.0/+esm');
|
||||
|
||||
const { durationMinutes, searchRange, workHours } = constraints;
|
||||
const searchStart = parseISO(searchRange.start);
|
||||
const searchEnd = parseISO(searchRange.end);
|
||||
|
||||
const [workStartHour, workStartMin] = workHours.start.split(':').map(Number);
|
||||
const [workEndHour, workEndMin] = workHours.end.split(':').map(Number);
|
||||
const workStartMs = (workStartHour * 60 + workStartMin) * 60000;
|
||||
const workEndMs = (workEndHour * 60 + workEndMin) * 60000;
|
||||
const parseTime = (timeStr) => {
|
||||
const [h, m] = timeStr.split(':').map(Number);
|
||||
return h * 60 + m;
|
||||
};
|
||||
|
||||
const workStartMinutes = parseTime(workHours.start);
|
||||
const workEndMinutes = parseTime(workHours.end);
|
||||
|
||||
const getUTCMinutes = (date) => date.getUTCHours() * 60 + date.getUTCMinutes();
|
||||
|
||||
const isInWorkHours = (date) => {
|
||||
const minutes = getUTCMinutes(date);
|
||||
return minutes >= workStartMinutes && minutes < workEndMinutes;
|
||||
};
|
||||
|
||||
const setUTCTime = (date, minutes) => {
|
||||
const d = new Date(date);
|
||||
d.setUTCHours(Math.floor(minutes / 60), minutes % 60, 0, 0);
|
||||
return d;
|
||||
};
|
||||
|
||||
const allBusy = [...calendar1, ...calendar2]
|
||||
.map(({ start, end }) => ({ start: parseISO(start), end: parseISO(end) }))
|
||||
.map(slot => ({ start: parseISO(slot.start), end: parseISO(slot.end) }))
|
||||
.sort((a, b) => a.start - b.start);
|
||||
|
||||
const merged = [];
|
||||
for (const slot of allBusy) {
|
||||
if (merged.length && slot.start <= merged[merged.length - 1].end) {
|
||||
merged[merged.length - 1].end = new Date(Math.max(merged[merged.length - 1].end, slot.end));
|
||||
if (merged.length === 0) {
|
||||
merged.push({ ...slot });
|
||||
} else {
|
||||
merged.push({ start: slot.start, end: slot.end });
|
||||
const last = merged[merged.length - 1];
|
||||
if (isBefore(slot.start, last.end) || isEqual(slot.start, last.end)) {
|
||||
last.end = isAfter(slot.end, last.end) ? slot.end : last.end;
|
||||
} else {
|
||||
merged.push({ ...slot });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const free = [];
|
||||
let current = searchStart;
|
||||
const freePeriods = [];
|
||||
let currentStart = searchStart;
|
||||
|
||||
for (const busy of merged) {
|
||||
if (current < busy.start) {
|
||||
free.push({ start: current, end: busy.start });
|
||||
if (isBefore(currentStart, busy.start)) {
|
||||
freePeriods.push({ start: currentStart, end: busy.start });
|
||||
}
|
||||
current = new Date(Math.max(current, busy.end));
|
||||
currentStart = isAfter(busy.end, currentStart) ? busy.end : currentStart;
|
||||
}
|
||||
if (current < searchEnd) {
|
||||
free.push({ start: current, end: searchEnd });
|
||||
|
||||
if (isBefore(currentStart, searchEnd)) {
|
||||
freePeriods.push({ start: currentStart, end: searchEnd });
|
||||
}
|
||||
|
||||
const slots = [];
|
||||
for (const period of free) {
|
||||
let slotStart = period.start;
|
||||
|
||||
for (const period of freePeriods) {
|
||||
let current = new Date(period.start);
|
||||
const periodEnd = period.end;
|
||||
|
||||
while (slotStart < period.end) {
|
||||
const dayStart = startOfDay(slotStart);
|
||||
const slotStartMs = slotStart - dayStart;
|
||||
const slotEnd = addMinutes(slotStart, durationMinutes);
|
||||
const slotEndMs = slotEnd - dayStart;
|
||||
while (isBefore(current, periodEnd)) {
|
||||
const currentDay = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate()));
|
||||
const workStart = setUTCTime(currentDay, workStartMinutes);
|
||||
const workEnd = setUTCTime(currentDay, workEndMinutes);
|
||||
|
||||
if (slotEnd > period.end) break;
|
||||
let slotStart = isAfter(current, workStart) ? current : workStart;
|
||||
|
||||
const endsNextDay = slotEnd - startOfDay(slotEnd) < slotEndMs % 86400000;
|
||||
|
||||
if (!endsNextDay &&
|
||||
slotStartMs >= workStartMs &&
|
||||
slotEndMs <= workEndMs &&
|
||||
slotStart >= searchStart &&
|
||||
slotEnd <= searchEnd) {
|
||||
slots.push({
|
||||
start: formatISO(slotStart),
|
||||
end: formatISO(slotEnd)
|
||||
});
|
||||
if (!isBefore(slotStart, workEnd) || !isBefore(slotStart, periodEnd)) {
|
||||
const nextDay = new Date(currentDay);
|
||||
nextDay.setUTCDate(nextDay.getUTCDate() + 1);
|
||||
current = nextDay;
|
||||
continue;
|
||||
}
|
||||
|
||||
slotStart = slotEnd;
|
||||
const slotEnd = addMinutes(slotStart, durationMinutes);
|
||||
|
||||
if ((isInWorkHours(slotStart) && isInWorkHours(new Date(slotEnd.getTime() - 1))) &&
|
||||
(isBefore(slotEnd, periodEnd) || isEqual(slotEnd, periodEnd)) &&
|
||||
(isBefore(slotEnd, workEnd) || isEqual(slotEnd, workEnd))) {
|
||||
slots.push({
|
||||
start: slotStart.toISOString(),
|
||||
end: slotEnd.toISOString()
|
||||
});
|
||||
current = slotEnd;
|
||||
} else {
|
||||
const nextDay = new Date(currentDay);
|
||||
nextDay.setUTCDate(nextDay.getUTCDate() + 1);
|
||||
current = nextDay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
};
|
||||
export default findAvailableSlots;
|
||||
export default findAvailableSlots;
|
||||
// Generation time: 14.710s
|
||||
// Result: PASS
|
||||
@@ -1,74 +0,0 @@
|
||||
async function findAvailableSlots(calendar1, calendar2, constraints) {
|
||||
const {
|
||||
parseISO, addMinutes, addDays, max, isBefore, isAfter, startOfDay,
|
||||
} = await import('https://cdn.jsdelivr.net/npm/date-fns@3.6.0/esm/index.js');
|
||||
|
||||
const { durationMinutes, searchRange, workHours } = constraints;
|
||||
const searchStart = parseISO(searchRange.start);
|
||||
const searchEnd = parseISO(searchRange.end);
|
||||
const [workStartH, workStartM] = workHours.start.split(':').map(Number);
|
||||
const [workEndH, workEndM] = workHours.end.split(':').map(Number);
|
||||
|
||||
const busySlots = [...calendar1, ...calendar2]
|
||||
.map(slot => ({ start: parseISO(slot.start), end: parseISO(slot.end) }))
|
||||
.sort((a, b) => a.start - b.start);
|
||||
|
||||
const mergedBusy = busySlots.reduce((acc, current) => {
|
||||
const last = acc.at(-1);
|
||||
if (last && isBefore(current.start, last.end)) {
|
||||
last.end = max([last.end, current.end]);
|
||||
} else {
|
||||
acc.push({ ...current });
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const freeIntervals = [];
|
||||
let cursor = searchStart;
|
||||
|
||||
mergedBusy.forEach(busy => {
|
||||
if (isBefore(cursor, busy.start)) {
|
||||
freeIntervals.push({ start: cursor, end: busy.start });
|
||||
}
|
||||
cursor = max([cursor, busy.end]);
|
||||
});
|
||||
|
||||
if (isBefore(cursor, searchEnd)) {
|
||||
freeIntervals.push({ start: cursor, end: searchEnd });
|
||||
}
|
||||
|
||||
const availableSlots = freeIntervals.flatMap(gap => {
|
||||
const slotsInGap = [];
|
||||
let slotCursor = gap.start;
|
||||
|
||||
while (isBefore(slotCursor, gap.end)) {
|
||||
const day = startOfDay(slotCursor);
|
||||
const workDayStart = new Date(day);
|
||||
workDayStart.setUTCHours(workStartH, workStartM, 0, 0);
|
||||
|
||||
const workDayEnd = new Date(day);
|
||||
workDayEnd.setUTCHours(workEndH, workEndM, 0, 0);
|
||||
|
||||
const slotStart = max([slotCursor, workDayStart]);
|
||||
const slotEnd = addMinutes(slotStart, durationMinutes);
|
||||
|
||||
const canFit = !isAfter(slotEnd, workDayEnd) && !isAfter(slotEnd, gap.end);
|
||||
|
||||
if (canFit) {
|
||||
slotsInGap.push({ start: slotStart, end: slotEnd });
|
||||
slotCursor = slotEnd;
|
||||
} else {
|
||||
const nextDayStart = addDays(day, 1);
|
||||
nextDayStart.setUTCHours(workStartH, workStartM, 0, 0);
|
||||
slotCursor = nextDayStart;
|
||||
}
|
||||
}
|
||||
return slotsInGap;
|
||||
});
|
||||
|
||||
return availableSlots.map(slot => ({
|
||||
start: slot.start.toISOString(),
|
||||
end: slot.end.toISOString(),
|
||||
}));
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
@@ -1,52 +1,65 @@
|
||||
const findAvailableSlots = async (cal1, cal2, { durationMinutes: dur, searchRange: range, workHours: work }) => {
|
||||
const { parseISO } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.6.0/+esm');
|
||||
const findAvailableSlots = async (calA, calB, { durationMinutes, searchRange, workHours }) => {
|
||||
const { addMinutes, parseISO, formatISO } = await import('https://esm.sh/date-fns@2.30.0');
|
||||
|
||||
const getMins = (t) => { const [h, m] = t.split(':'); return (+h * 60) + +m; };
|
||||
const [workStart, workEnd] = [workHours.start, workHours.end].map(getMins);
|
||||
const rangeEnd = parseISO(searchRange.end).getTime();
|
||||
|
||||
const busy = [...calA, ...calB]
|
||||
.map(s => ({ s: parseISO(s.start).getTime(), e: parseISO(s.end).getTime() }))
|
||||
.sort((a, b) => a.s - b.s)
|
||||
.reduce((acc, c) => {
|
||||
const last = acc[acc.length - 1];
|
||||
if (last && c.s <= last.e) last.e = Math.max(last.e, c.e);
|
||||
else acc.push(c);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
let current = parseISO(searchRange.start).getTime();
|
||||
const slots = [];
|
||||
|
||||
while (current + durationMinutes * 60000 <= rangeEnd) {
|
||||
const d = new Date(current);
|
||||
const curMins = d.getUTCHours() * 60 + d.getUTCMinutes();
|
||||
|
||||
if (curMins >= workEnd) {
|
||||
d.setUTCDate(d.getUTCDate() + 1);
|
||||
d.setUTCHours(0, 0, 0, 0);
|
||||
current = addMinutes(d, workStart).getTime();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (curMins < workStart) {
|
||||
d.setUTCHours(0, 0, 0, 0);
|
||||
current = addMinutes(d, workStart).getTime();
|
||||
continue;
|
||||
}
|
||||
|
||||
const end = addMinutes(current, durationMinutes).getTime();
|
||||
const endD = new Date(end);
|
||||
const endMins = endD.getUTCHours() * 60 + endD.getUTCMinutes();
|
||||
|
||||
if (end > rangeEnd) break;
|
||||
|
||||
if (endD.getUTCDate() !== d.getUTCDate() || endMins > workEnd) {
|
||||
d.setUTCDate(d.getUTCDate() + 1);
|
||||
d.setUTCHours(0, 0, 0, 0);
|
||||
current = addMinutes(d, workStart).getTime();
|
||||
continue;
|
||||
}
|
||||
|
||||
const conflict = busy.find(b => current < b.e && end > b.s);
|
||||
|
||||
const toMs = (d) => parseISO(d).getTime();
|
||||
const [wsH, wsM] = work.start.split(':').map(Number);
|
||||
const [weH, weM] = work.end.split(':').map(Number);
|
||||
const rangeStart = toMs(range.start);
|
||||
const rangeEnd = toMs(range.end);
|
||||
const durMs = dur * 60000;
|
||||
|
||||
const busy = [...cal1, ...cal2]
|
||||
.map(x => ({ s: toMs(x.start), e: toMs(x.end) }))
|
||||
.sort((a, b) => a.s - b.s);
|
||||
|
||||
const merged = [];
|
||||
for (const b of busy) {
|
||||
const last = merged[merged.length - 1];
|
||||
if (last && b.s < last.e) last.e = Math.max(last.e, b.e);
|
||||
else merged.push(b);
|
||||
if (conflict) {
|
||||
current = conflict.e;
|
||||
} else {
|
||||
slots.push({ start: formatISO(current), end: formatISO(end) });
|
||||
current = end;
|
||||
}
|
||||
}
|
||||
|
||||
const slots = [];
|
||||
let currDate = parseISO(range.start);
|
||||
currDate.setUTCHours(0, 0, 0, 0);
|
||||
|
||||
while (currDate.getTime() < rangeEnd) {
|
||||
const wStart = new Date(currDate).setUTCHours(wsH, wsM, 0, 0);
|
||||
const wEnd = new Date(currDate).setUTCHours(weH, weM, 0, 0);
|
||||
|
||||
let t = Math.max(wStart, rangeStart);
|
||||
const limit = Math.min(wEnd, rangeEnd);
|
||||
|
||||
while (t + durMs <= limit) {
|
||||
const tEnd = t + durMs;
|
||||
const clash = merged.find(b => t < b.e && tEnd > b.s);
|
||||
|
||||
if (clash) {
|
||||
t = clash.e;
|
||||
} else {
|
||||
slots.push({
|
||||
start: new Date(t).toISOString(),
|
||||
end: new Date(tEnd).toISOString()
|
||||
});
|
||||
t += durMs;
|
||||
}
|
||||
}
|
||||
currDate.setUTCDate(currDate.getUTCDate() + 1);
|
||||
}
|
||||
|
||||
return slots;
|
||||
return slots;
|
||||
};
|
||||
export default findAvailableSlots;
|
||||
export default findAvailableSlots;
|
||||
// Generation time: 47.831s
|
||||
// Result: PASS
|
||||
@@ -1,11 +1,56 @@
|
||||
async function findAvailableSlots(a,b,{durationMinutes:d,searchRange:r,workHours:w}){
|
||||
const{parseISO:p,formatISO:f,addMinutes:m,min:n,max:x,startOfDay:s}=await import('https://esm.sh/date-fns');
|
||||
const busy=[...a,...b].map(({start:S,end:E})=>({s:p(S),e:p(E)})).sort((q,y)=>q.s-y.s).reduce((c,{s:S,e:E})=>{
|
||||
const l=c[c.length-1];if(!l||S>l.e)c.push({s:S,e:E});else l.e=x([l.e,E]);return c;
|
||||
},[]);
|
||||
const rs=p(r.start),re=p(r.end),[ws,we]=[w.start,w.end].map(t=>{const[h,m]=t.split(':').map(Number);return h*60+m;});
|
||||
const free=[];let cur=rs;for(const{s:S,e:E}of busy){S>cur&&free.push({s:cur,e:n([S,re])});cur=x([cur,E]);if(cur>=re)break;}
|
||||
cur<re&&free.push({s:cur,e:re});const slots=[];for(const{s:fs,e:fe}of free){let st=fs;while(m(st,d)<=fe){const en=m(st,d);const minutes=(st-s(st))/6e4;if(minutes>=ws&&minutes+d<=we)slots.push({start:f(st),end:f(en)});st=en;}}
|
||||
return slots;
|
||||
export async function findAvailableSlots(cal1, cal2, { durationMinutes, searchRange, workHours }) {
|
||||
const { parseISO, compareAsc, addMinutes } = await import('https://cdn.skypack.dev/date-fns');
|
||||
|
||||
const s = parseISO(searchRange.start);
|
||||
const e = parseISO(searchRange.end);
|
||||
|
||||
const [whS, whE] = [workHours.start, workHours.end].map(t => {
|
||||
const [h, m] = t.split(':').map(Number);
|
||||
return h * 60 + m;
|
||||
});
|
||||
|
||||
const inWH = (d, de) => {
|
||||
const g = t => t.getUTCHours() * 60 + t.getUTCMinutes();
|
||||
return g(d) >= whS && g(de) <= whE;
|
||||
};
|
||||
|
||||
const busy = [...cal1, ...cal2]
|
||||
.map(({ start, end }) => ({ s: parseISO(start), e: parseISO(end) }))
|
||||
.filter(({ s: bs, e: be }) => compareAsc(be, s) > 0 && compareAsc(bs, e) < 0)
|
||||
.map(({ s: bs, e: be }) => ({
|
||||
s: compareAsc(bs, s) < 0 ? s : bs,
|
||||
e: compareAsc(be, e) > 0 ? e : be
|
||||
}))
|
||||
.sort((a, b) => compareAsc(a.s, b.s));
|
||||
|
||||
const merged = [];
|
||||
for (const { s: bs, e: be } of busy) {
|
||||
const last = merged[merged.length - 1];
|
||||
if (!last || compareAsc(bs, last.e) >= 0) merged.push({ s: bs, e: be });
|
||||
else if (compareAsc(be, last.e) > 0) last.e = be;
|
||||
}
|
||||
|
||||
const free = [];
|
||||
let cur = s;
|
||||
for (const { s: ms, e: me } of merged) {
|
||||
if (compareAsc(cur, ms) < 0) free.push({ s: cur, e: ms });
|
||||
cur = compareAsc(me, cur) > 0 ? me : cur;
|
||||
}
|
||||
if (compareAsc(cur, e) < 0) free.push({ s: cur, e });
|
||||
|
||||
const slots = [];
|
||||
for (const { s: fs, e: fe } of free) {
|
||||
let cs = fs;
|
||||
while (true) {
|
||||
const ce = addMinutes(cs, durationMinutes);
|
||||
if (compareAsc(ce, fe) > 0) break;
|
||||
if (inWH(cs, ce)) slots.push({ start: cs.toISOString(), end: ce.toISOString() });
|
||||
cs = addMinutes(cs, durationMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
export default findAvailableSlots;
|
||||
// Generation time: 289.823s
|
||||
// Result: PASS
|
||||
@@ -1,66 +1,93 @@
|
||||
const useDayjs=(()=>{
|
||||
let p
|
||||
return()=>p||(p=(async()=>{
|
||||
const [{default:d},{default:u}]=await Promise.all([
|
||||
import('https://cdn.jsdelivr.net/npm/dayjs@1/esm/index.js'),
|
||||
import('https://cdn.jsdelivr.net/npm/dayjs@1/esm/plugin/utc/index.js')
|
||||
])
|
||||
d.extend(u)
|
||||
return d
|
||||
})())
|
||||
const loadDay = (() => {
|
||||
let memo
|
||||
return () => memo ?? (memo = (async () => {
|
||||
const [core, utc] = await Promise.all([
|
||||
import('https://esm.sh/dayjs@1.11.13?target=esnext'),
|
||||
import('https://esm.sh/dayjs@1.11.13/plugin/utc?target=esnext')
|
||||
])
|
||||
const d = core.default
|
||||
d.extend(utc.default)
|
||||
return d
|
||||
})())
|
||||
})()
|
||||
|
||||
async function findAvailableSlots(c1=[],c2=[],cfg={}){
|
||||
const d=await useDayjs()
|
||||
const {durationMinutes:dur,searchRange:r={},workHours:w={}}=cfg
|
||||
const {start:rs,end:re}=r
|
||||
const {start:ws,end:we}=w
|
||||
if(!dur||dur<=0||!rs||!re||!ws||!we)return []
|
||||
const s=d.utc(rs),e=d.utc(re)
|
||||
if(!s.isValid()||!e.isValid()||e.valueOf()<=s.valueOf())return []
|
||||
const rangeStart=s.valueOf(),rangeEnd=e.valueOf(),min=60000
|
||||
const clip=v=>{
|
||||
if(!v||!v.start||!v.end)return 0
|
||||
const a=d.utc(v.start),b=d.utc(v.end)
|
||||
if(!a.isValid()||!b.isValid())return 0
|
||||
const st=Math.max(rangeStart,a.valueOf()),en=Math.min(rangeEnd,b.valueOf())
|
||||
return en>st?{start:st,end:en}:0
|
||||
}
|
||||
const busy=[...c1,...c2].map(clip).filter(Boolean).sort((x,y)=>x.start-y.start)
|
||||
const merged=[]
|
||||
for(const slot of busy){
|
||||
const last=merged[merged.length-1]
|
||||
if(!last||slot.start>last.end)merged.push({...slot})
|
||||
else if(slot.end>last.end)last.end=slot.end
|
||||
}
|
||||
const free=[]
|
||||
let cur=rangeStart
|
||||
for(const slot of merged){
|
||||
if(slot.start>cur)free.push({start:cur,end:slot.start})
|
||||
cur=Math.max(cur,slot.end)
|
||||
}
|
||||
if(cur<rangeEnd)free.push({start:cur,end:rangeEnd})
|
||||
const minutes=t=>{const [h,m]=t.split(':').map(Number);return h*60+m}
|
||||
const workStart=minutes(ws),workEnd=minutes(we)
|
||||
if(workStart>=workEnd)return []
|
||||
const out=[]
|
||||
for(const span of free){
|
||||
let day=d.utc(span.start).startOf('day')
|
||||
while(day.valueOf()<span.end){
|
||||
const dayStart=day.add(workStart,'minute'),dayEnd=day.add(workEnd,'minute')
|
||||
const winStart=Math.max(dayStart.valueOf(),span.start),winEnd=Math.min(dayEnd.valueOf(),span.end)
|
||||
if(winEnd-winStart>=dur*min){
|
||||
let slotStart=d.utc(winStart)
|
||||
while(true){
|
||||
const slotEnd=slotStart.add(dur,'minute')
|
||||
if(slotEnd.valueOf()>winEnd)break
|
||||
out.push({start:slotStart.toISOString(),end:slotEnd.toISOString()})
|
||||
slotStart=slotEnd
|
||||
}
|
||||
}
|
||||
day=day.add(1,'day')
|
||||
const findAvailableSlots = async (c1 = [], c2 = [], cfg = {}) => {
|
||||
const d = await loadDay()
|
||||
const u = v => d.utc(v)
|
||||
const {
|
||||
durationMinutes: dm,
|
||||
searchRange: sr = {},
|
||||
workHours: wh = {}
|
||||
} = cfg
|
||||
const dur = Number(dm)
|
||||
if(!Number.isFinite(dur) || dur <= 0 || !sr.start || !sr.end || !wh.start || !wh.end) return []
|
||||
const s = u(sr.start)
|
||||
const e = u(sr.end)
|
||||
if(!s.isValid() || !e.isValid() || !s.isBefore(e)) return []
|
||||
const toMin = v => {
|
||||
const [h, m = 0] = String(v).split(':').map(Number)
|
||||
if(!Number.isFinite(h) || !Number.isFinite(m)) return null
|
||||
if(h < 0 || h > 24 || m < 0 || m > 59) return null
|
||||
if(h === 24 && m > 0) return null
|
||||
return h * 60 + m
|
||||
}
|
||||
}
|
||||
return out
|
||||
const ws = toMin(wh.start)
|
||||
const we = toMin(wh.end)
|
||||
if(ws == null || we == null || ws >= we) return []
|
||||
const list = [
|
||||
...(Array.isArray(c1) ? c1 : []),
|
||||
...(Array.isArray(c2) ? c2 : [])
|
||||
]
|
||||
const busy = list.map(v => {
|
||||
if(!v?.start || !v?.end) return null
|
||||
const st = u(v.start)
|
||||
const en = u(v.end)
|
||||
if(!st.isValid() || !en.isValid() || !st.isBefore(en)) return null
|
||||
if(!en.isAfter(s) || !st.isBefore(e)) return null
|
||||
return {
|
||||
start: st.isBefore(s) ? s : st,
|
||||
end: en.isAfter(e) ? e : en
|
||||
}
|
||||
}).filter(Boolean).sort((a, b) => a.start.valueOf() - b.start.valueOf())
|
||||
const merged = []
|
||||
for(const slot of busy){
|
||||
if(!merged.length){
|
||||
merged.push({...slot})
|
||||
continue
|
||||
}
|
||||
const last = merged[merged.length - 1]
|
||||
if(slot.start.isAfter(last.end)) merged.push({...slot})
|
||||
else if(slot.end.isAfter(last.end)) last.end = slot.end
|
||||
}
|
||||
const free = []
|
||||
let cur = s
|
||||
for(const slot of merged){
|
||||
if(slot.start.isAfter(cur)) free.push({start: cur, end: slot.start})
|
||||
if(slot.end.isAfter(cur)) cur = slot.end
|
||||
}
|
||||
if(cur.isBefore(e)) free.push({start: cur, end: e})
|
||||
if(!free.length) return []
|
||||
const step = dur * 60000
|
||||
if(!Number.isFinite(step) || step <= 0) return []
|
||||
const out = []
|
||||
for(const seg of free){
|
||||
for(let day = seg.start.startOf('day'); day.isBefore(seg.end); day = day.add(1, 'day')){
|
||||
const wsStart = day.add(ws, 'minute')
|
||||
const wsEnd = day.add(we, 'minute')
|
||||
const start = wsStart.isAfter(seg.start) ? wsStart : seg.start
|
||||
const end = wsEnd.isBefore(seg.end) ? wsEnd : seg.end
|
||||
if(!start.isBefore(end)) continue
|
||||
const limit = end.valueOf()
|
||||
for(let t = start.valueOf(); t + step <= limit; t += step){
|
||||
out.push({
|
||||
start: d.utc(t).toISOString(),
|
||||
end: d.utc(t + step).toISOString()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
export default findAvailableSlots;
|
||||
// Generation time: 211.798s
|
||||
// Result: PASS
|
||||
@@ -1,71 +0,0 @@
|
||||
const findAvailableSlots = async (calendar1, calendar2, constraints) => {
|
||||
const { DateTime, Interval } = await import('https://cdn.skypack.dev/luxon@3.0.1')
|
||||
|
||||
const { durationMinutes, searchRange, workHours } = constraints
|
||||
const workStart = DateTime.fromISO(`${searchRange.start.split('T')[0]}T${workHours.start}:00Z`)
|
||||
const workEnd = DateTime.fromISO(`${searchRange.start.split('T')[0]}T${workHours.end}:00Z`)
|
||||
const searchStart = DateTime.fromISO(searchRange.start)
|
||||
const searchEnd = DateTime.fromISO(searchRange.end)
|
||||
|
||||
const mergeCalendars = (cal1, cal2) => {
|
||||
const allSlots = [...cal1, ...cal2].map(slot => ({
|
||||
start: DateTime.fromISO(slot.start),
|
||||
end: DateTime.fromISO(slot.end)
|
||||
})).sort((a, b) => a.start - b.start)
|
||||
|
||||
return allSlots.reduce((merged, current) => {
|
||||
if (merged.length === 0) return [current]
|
||||
|
||||
const last = merged[merged.length - 1]
|
||||
if (current.start <= last.end) {
|
||||
last.end = current.end > last.end ? current.end : last.end
|
||||
return merged
|
||||
}
|
||||
|
||||
return [...merged, current]
|
||||
}, [])
|
||||
}
|
||||
|
||||
const mergedBusy = mergeCalendars(calendar1, calendar2)
|
||||
const freeIntervals = []
|
||||
|
||||
let currentStart = searchStart
|
||||
for (const busy of mergedBusy) {
|
||||
if (busy.start > currentStart) {
|
||||
freeIntervals.push(Interval.fromDateTimes(currentStart, busy.start))
|
||||
}
|
||||
currentStart = busy.end > currentStart ? busy.end : currentStart
|
||||
}
|
||||
|
||||
if (currentStart < searchEnd) {
|
||||
freeIntervals.push(Interval.fromDateTimes(currentStart, searchEnd))
|
||||
}
|
||||
|
||||
const availableSlots = freeIntervals.flatMap(interval => {
|
||||
const slots = []
|
||||
let slotStart = interval.start
|
||||
|
||||
while (slotStart.plus({ minutes: durationMinutes }) <= interval.end) {
|
||||
const slotEnd = slotStart.plus({ minutes: durationMinutes })
|
||||
const slotInterval = Interval.fromDateTimes(slotStart, slotEnd)
|
||||
|
||||
if (slotInterval.engulfs(workStart) && slotInterval.engulfs(workEnd)) {
|
||||
slots.push({
|
||||
start: slotStart.toISO(),
|
||||
end: slotEnd.toISO()
|
||||
})
|
||||
}
|
||||
|
||||
slotStart = slotEnd
|
||||
}
|
||||
|
||||
return slots
|
||||
})
|
||||
|
||||
return availableSlots.filter(slot => {
|
||||
const slotStart = DateTime.fromISO(slot.start)
|
||||
const slotEnd = DateTime.fromISO(slot.end)
|
||||
return slotStart >= workStart && slotEnd <= workEnd
|
||||
})
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
@@ -1,57 +0,0 @@
|
||||
async function findAvailableSlots(cal1, cal2, {durationMinutes:dm, searchRange, workHours}) {
|
||||
const {DateTime:DT, Interval, Duration} = await import('https://cdn.skypack.dev/luxon');
|
||||
const dur=Duration.fromObject({minutes:dm});
|
||||
const srS=DT.fromISO(searchRange.start).toUTC();
|
||||
const srE=DT.fromISO(searchRange.end).toUTC();
|
||||
const srI=Interval.fromDateTimes(srS,srE);
|
||||
let busies=[...cal1,...cal2].map(s=>{
|
||||
const a=DT.fromISO(s.start).toUTC(),b=DT.fromISO(s.end).toUTC();
|
||||
return a<b?Interval.fromDateTimes(a,b).intersection(srI):null;
|
||||
}).filter(Boolean);
|
||||
const [ws,we]=[workHours.start,workHours.end];
|
||||
const hms=+ws.slice(0,2),mms=+ws.slice(3,5),hme=+we.slice(0,2),mme=+we.slice(3,5);
|
||||
let cur=srS.startOf('day');
|
||||
while(cur<srE){
|
||||
const dayE=cur.plus({days:1});
|
||||
const dayI=Interval.fromDateTimes(cur,dayE).intersection(srI);
|
||||
if(dayI.isEmpty) {cur=cur.plus({days:1});continue;}
|
||||
const wsT=cur.set({hour:hms,minute:mms,second:0,millisecond:0});
|
||||
const weT=cur.set({hour:hme,minute:mme,second:0,millisecond:0});
|
||||
const workI=Interval.fromDateTimes(wsT,weT).intersection(dayI);
|
||||
if(!workI?.isValid||workI.isEmpty){
|
||||
busies.push(dayI);
|
||||
}else{
|
||||
if(dayI.start<workI.start)busies.push(Interval.fromDateTimes(dayI.start,workI.start));
|
||||
if(workI.end<dayI.end)busies.push(Interval.fromDateTimes(workI.end,dayI.end));
|
||||
}
|
||||
cur=cur.plus({days:1});
|
||||
}
|
||||
busies.sort((a,b)=>a.start.toMillis()-b.start.toMillis());
|
||||
const merged=[];
|
||||
for(let iv of busies){
|
||||
if(!iv?.isValid||iv.isEmpty)continue;
|
||||
if(merged.length===0||merged.at(-1).end<iv.start){
|
||||
merged.push(iv);
|
||||
}else{
|
||||
const last=merged[merged.length-1];
|
||||
merged[merged.length-1]=Interval.fromDateTimes(last.start,iv.end>last.end?iv.end:last.end);
|
||||
}
|
||||
}
|
||||
const frees=[];
|
||||
let prev=srS;
|
||||
for(let b of merged){
|
||||
if(prev<b.start)frees.push(Interval.fromDateTimes(prev,b.start));
|
||||
prev=b.end>prev?b.end:prev;
|
||||
}
|
||||
if(prev<srE)frees.push(Interval.fromDateTimes(prev,srE));
|
||||
const slots=[];
|
||||
for(let f of frees){
|
||||
let c=f.start;
|
||||
while(c.plus(dur)<=f.end){
|
||||
slots.push({start:c.toISO(),end:c.plus(dur).toISO()});
|
||||
c=c.plus(dur);
|
||||
}
|
||||
}
|
||||
return slots;
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
@@ -1,64 +0,0 @@
|
||||
async function findAvailableSlots(cal1, cal2, constraints) {
|
||||
const { DateTime, Interval } = await import('https://esm.sh/luxon@3');
|
||||
const busySlots = [...cal1, ...cal2].map(slot => {
|
||||
const s = DateTime.fromISO(slot.start, { zone: 'utc' });
|
||||
const e = DateTime.fromISO(slot.end, { zone: 'utc' });
|
||||
return s.isValid && e.isValid && s < e ? Interval.fromDateTimes(s, e) : null;
|
||||
}).filter(Boolean);
|
||||
const mergedBusies = Interval.union(busySlots);
|
||||
const rangeStart = DateTime.fromISO(constraints.searchRange.start, { zone: 'utc' });
|
||||
const rangeEnd = DateTime.fromISO(constraints.searchRange.end, { zone: 'utc' });
|
||||
const searchInt = Interval.fromDateTimes(rangeStart, rangeEnd);
|
||||
let covered = mergedBusies
|
||||
.filter(b => searchInt.overlaps(b))
|
||||
.map(b => searchInt.intersection(b))
|
||||
.filter(i => i.isValid);
|
||||
covered.sort((a, b) => a.start.toMillis() - b.start.toMillis());
|
||||
const frees = [];
|
||||
let current = rangeStart;
|
||||
for (const busy of covered) {
|
||||
if (current < busy.start) {
|
||||
frees.push(Interval.fromDateTimes(current, busy.start));
|
||||
}
|
||||
current = DateTime.max(current, busy.end);
|
||||
}
|
||||
if (current < rangeEnd) {
|
||||
frees.push(Interval.fromDateTimes(current, rangeEnd));
|
||||
}
|
||||
const [wsH, wsM] = constraints.workHours.start.split(':').map(Number);
|
||||
const [weH, weM] = constraints.workHours.end.split(':').map(Number);
|
||||
const durMin = constraints.durationMinutes;
|
||||
let workInts = [];
|
||||
let curDay = rangeStart.startOf('day');
|
||||
const endDayStart = rangeEnd.startOf('day');
|
||||
while (curDay <= endDayStart) {
|
||||
const dayWorkS = curDay.set({ hour: wsH, minute: wsM });
|
||||
const dayWorkE = curDay.set({ hour: weH, minute: weM });
|
||||
if (dayWorkS < dayWorkE) {
|
||||
workInts.push(Interval.fromDateTimes(dayWorkS, dayWorkE));
|
||||
}
|
||||
curDay = curDay.plus({ days: 1 });
|
||||
}
|
||||
const allowables = [];
|
||||
for (const free of frees) {
|
||||
for (const work of workInts) {
|
||||
const inter = free.intersection(work);
|
||||
if (inter.isValid) allowables.push(inter);
|
||||
}
|
||||
}
|
||||
const mergedAllows = Interval.union(allowables);
|
||||
const availableSlots = [];
|
||||
for (const allow of mergedAllows) {
|
||||
let slotStart = allow.start;
|
||||
while (allow.contains(slotStart.plus({ minutes: durMin }))) {
|
||||
const slotEnd = slotStart.plus({ minutes: durMin });
|
||||
availableSlots.push({
|
||||
start: slotStart.toISO(),
|
||||
end: slotEnd.toISO()
|
||||
});
|
||||
slotStart = slotEnd;
|
||||
}
|
||||
}
|
||||
return availableSlots;
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
48
tests/7_scheduler/outputs/x-ai_grok-4.js
Normal file
48
tests/7_scheduler/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,48 @@
|
||||
async function findAvailableSlots(c1, c2, con) {
|
||||
const {DateTime, Interval} = await import('https://cdn.jsdelivr.net/npm/luxon@3.4.4/+esm');
|
||||
const st = DateTime.fromISO(con.searchRange.start, {zone:'utc'});
|
||||
const ed = DateTime.fromISO(con.searchRange.end, {zone:'utc'});
|
||||
const sr = Interval.fromDateTimes(st, ed);
|
||||
let bs = [...c1, ...c2].map(({start, end}) => Interval.fromDateTimes(
|
||||
DateTime.fromISO(start, {zone:'utc'}),
|
||||
DateTime.fromISO(end, {zone:'utc'})
|
||||
));
|
||||
let cur = st.startOf('day');
|
||||
const [wh, wm] = con.workHours.start.split(':').map(Number);
|
||||
const [eh, em] = con.workHours.end.split(':').map(Number);
|
||||
while (cur <= ed) {
|
||||
const ws = cur.set({hour: wh, minute: wm});
|
||||
const we = cur.set({hour: eh, minute: em});
|
||||
if (cur < ws) bs.push(Interval.fromDateTimes(cur, ws));
|
||||
const eod = cur.endOf('day');
|
||||
if (we < eod) bs.push(Interval.fromDateTimes(we, eod));
|
||||
cur = cur.plus({days:1}).startOf('day');
|
||||
}
|
||||
let mb = Interval.merge(bs).sort((a,b) => a.start.toMillis() - b.start.toMillis());
|
||||
let rb = mb.filter(i => i.overlaps(sr));
|
||||
let free = [];
|
||||
if (rb.length === 0) {
|
||||
free.push(sr);
|
||||
} else {
|
||||
if (sr.start < rb[0].start) free.push(Interval.fromDateTimes(sr.start, rb[0].start));
|
||||
for (let i = 0; i < rb.length - 1; i++) {
|
||||
free.push(Interval.fromDateTimes(rb[i].end, rb[i + 1].start));
|
||||
}
|
||||
if (rb[rb.length - 1].end < sr.end) free.push(Interval.fromDateTimes(rb[rb.length - 1].end, sr.end));
|
||||
}
|
||||
const dur = con.durationMinutes;
|
||||
let av = [];
|
||||
for (let f of free) {
|
||||
let cs = f.start;
|
||||
while (true) {
|
||||
let ce = cs.plus({minutes: dur});
|
||||
if (ce > f.end) break;
|
||||
av.push({start: cs.toISO(), end: ce.toISO()});
|
||||
cs = ce;
|
||||
}
|
||||
}
|
||||
return av;
|
||||
}
|
||||
export default findAvailableSlots;
|
||||
// Generation time: 201.779s
|
||||
// Result: PASS
|
||||
@@ -1,18 +1,43 @@
|
||||
async function validateJSON(jsonObject, jsonSchema) {
|
||||
const { default: Ajv } = await import("https://esm.sh/ajv@8");
|
||||
const { default: addFormats } = await import("https://esm.sh/ajv-formats@3");
|
||||
|
||||
const ajv = new Ajv({ allErrors: true, strict: false });
|
||||
addFormats(ajv);
|
||||
|
||||
const validate = ajv.compile(jsonSchema);
|
||||
const valid = validate(jsonObject);
|
||||
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : validate.errors.map(e =>
|
||||
e.instancePath ? `${e.instancePath} ${e.message}` : e.message
|
||||
)
|
||||
};
|
||||
try {
|
||||
const Ajv = (await import('https://cdn.jsdelivr.net/npm/ajv@8/dist/ajv.min.js')).default
|
||||
|| (await import('https://esm.sh/ajv@8')).default;
|
||||
|
||||
const ajv = new Ajv({ allErrors: true, verbose: true });
|
||||
const validate = ajv.compile(jsonSchema);
|
||||
const valid = validate(jsonObject);
|
||||
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : validate.errors.map(e =>
|
||||
e.instancePath
|
||||
? `${e.instancePath} ${e.message}`
|
||||
: e.message
|
||||
)
|
||||
};
|
||||
} catch (e) {
|
||||
try {
|
||||
const { default: Ajv } = await import('https://esm.sh/ajv@8');
|
||||
const ajv = new Ajv({ allErrors: true, verbose: true });
|
||||
const validate = ajv.compile(jsonSchema);
|
||||
const valid = validate(jsonObject);
|
||||
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : validate.errors.map(e =>
|
||||
e.instancePath
|
||||
? `${e.instancePath} ${e.message}`
|
||||
: e.message
|
||||
)
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
valid: false,
|
||||
errors: [`Schema validation failed: ${err.message}`]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
export default validateJSON;
|
||||
export default validateJSON;
|
||||
// Generation time: 5.496s
|
||||
// Result: PASS
|
||||
@@ -1,11 +1,18 @@
|
||||
const validateJSON = async (data, schema) => {
|
||||
const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8/dist/2020.min.js');
|
||||
const ajv = new Ajv({ allErrors: true, strict: false });
|
||||
const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8.12.0/dist/2020.min.js');
|
||||
const ajv = new Ajv({ allErrors: true, verbose: true });
|
||||
const validate = ajv.compile(schema);
|
||||
const valid = validate(data);
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : validate.errors.map(e => `${e.instancePath || '/'} ${e.message}`)
|
||||
errors: valid ? [] : validate.errors.map(e => ({
|
||||
path: e.instancePath || '/',
|
||||
message: e.message,
|
||||
keyword: e.keyword,
|
||||
params: e.params
|
||||
}))
|
||||
};
|
||||
};
|
||||
export default validateJSON;
|
||||
export default validateJSON;
|
||||
// Generation time: 3.111s
|
||||
// Result: FAIL
|
||||
@@ -1,24 +0,0 @@
|
||||
const validateJSON = async (json, schema) => {
|
||||
let ajv;
|
||||
|
||||
try {
|
||||
const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8.17.1/+esm');
|
||||
ajv = new Ajv({ allErrors: true });
|
||||
} catch (e) {
|
||||
return { valid: false, errors: ["Failed to load validator: " + e.message] };
|
||||
}
|
||||
|
||||
try {
|
||||
const validate = ajv.compile(schema);
|
||||
const valid = validate(json);
|
||||
|
||||
const errors = validate.errors?.map(
|
||||
e => `${e.instancePath || 'root'} ${e.message}`.trim()
|
||||
) ?? [];
|
||||
|
||||
return { valid, errors };
|
||||
} catch (e) {
|
||||
return { valid: false, errors: ["Invalid schema: " + e.message] };
|
||||
}
|
||||
};
|
||||
export default validateJSON;
|
||||
@@ -1,10 +1,9 @@
|
||||
const validateJSON = async (d, s) => {
|
||||
const { default: A } = await import('https://esm.sh/ajv@8.17.1')
|
||||
const v = new A({ allErrors: true }).compile(s)
|
||||
const r = v(d)
|
||||
return {
|
||||
valid: r,
|
||||
errors: r ? [] : v.errors.map(e => `${e.instancePath} ${e.message}`.trim())
|
||||
}
|
||||
}
|
||||
export default validateJSON;
|
||||
const validateJSON = async (data, schema) => {
|
||||
const { default: Ajv } = await import('https://esm.sh/ajv@8.17.1');
|
||||
const validate = new Ajv({ allErrors: true }).compile(schema);
|
||||
const valid = validate(data);
|
||||
return { valid, errors: valid ? [] : validate.errors.map(e => `${e.instancePath} ${e.message}`.trim()) };
|
||||
};
|
||||
export default validateJSON;
|
||||
// Generation time: 20.754s
|
||||
// Result: PASS
|
||||
@@ -1,12 +1,24 @@
|
||||
let Ajv;
|
||||
async function validateJSON(json, schema) {
|
||||
if(!(json&&typeof json==='object')||!(schema===true||schema===false||(schema&&typeof schema==='object')))
|
||||
return{valid:false,errors:['Invalid input']};
|
||||
try{
|
||||
if(!Ajv){const m=await import('https://esm.sh/ajv@8');Ajv=m.default}
|
||||
const ajv=new Ajv({allErrors:true}),v=ajv.compile(schema);
|
||||
const valid=v(json);
|
||||
return{valid,errors:valid?[]:v.errors.map(e=>`${e.instancePath||'root'} ${e.message}`)};
|
||||
}catch(e){return{valid:false,errors:[e.message]}}
|
||||
}
|
||||
export default validateJSON;
|
||||
let a, c;
|
||||
|
||||
export const validateJSON = async (d, s) => {
|
||||
try {
|
||||
if (!a) {
|
||||
const { default: Ajv } = await import('https://esm.sh/ajv?bundle');
|
||||
a = new Ajv({ allErrors: true });
|
||||
c = new Map();
|
||||
}
|
||||
const k = JSON.stringify(s);
|
||||
if (!c.has(k)) c.set(k, a.compile(s));
|
||||
const v = c.get(k);
|
||||
const valid = v(d);
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : v.errors.map(e => `${e.instancePath || 'root'} ${e.message}`)
|
||||
};
|
||||
} catch (e) {
|
||||
return { valid: false, errors: [e.message] };
|
||||
}
|
||||
};
|
||||
export default validateJSON;
|
||||
// Generation time: 19.566s
|
||||
// Result: PASS
|
||||
@@ -1,2 +1,21 @@
|
||||
const validateJSON=(()=>{let a;return async(j,s)=>{a??=(async()=>{const{default:Ajv}=await import('https://esm.run/ajv@8');return new Ajv({allErrors:1});})();const v=await a,c=v.compile(s),valid=c(j);return{valid,errors:valid?[]:(c.errors||[]).map(e=>`${e.instancePath||'/'} ${e.message}`)}}})();
|
||||
export default validateJSON;
|
||||
const loadAjv = (() => {
|
||||
let ajv
|
||||
return async () => {
|
||||
if (!ajv) {
|
||||
const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8.12.0/dist/ajv.js')
|
||||
ajv = new Ajv({ allErrors: true, strict: false })
|
||||
}
|
||||
return ajv
|
||||
}
|
||||
})()
|
||||
|
||||
export const validateJSON = async (data, schema) => {
|
||||
const ajv = await loadAjv()
|
||||
const validate = ajv.compile(schema)
|
||||
const valid = validate(data)
|
||||
const errors = valid ? [] : validate.errors.map(e => `${e.instancePath || '/'} ${e.message}`)
|
||||
return { valid, errors }
|
||||
}
|
||||
export default validateJSON;
|
||||
// Generation time: 6.678s
|
||||
// Result: FAIL
|
||||
@@ -1,36 +0,0 @@
|
||||
const validateJSON = async (json, schema) => {
|
||||
try {
|
||||
const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8.12.0/+esm')
|
||||
const { default: addFormats } = await import('https://cdn.jsdelivr.net/npm/ajv-formats@2.1.1/+esm')
|
||||
|
||||
const ajv = new Ajv({
|
||||
allErrors: true,
|
||||
strict: false,
|
||||
validateSchema: true
|
||||
})
|
||||
|
||||
addFormats(ajv)
|
||||
|
||||
const validate = ajv.compile(schema)
|
||||
const valid = validate(json)
|
||||
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : validate.errors.map(err => ({
|
||||
message: err.message,
|
||||
instancePath: err.instancePath,
|
||||
schemaPath: err.schemaPath,
|
||||
params: err.params
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
return {
|
||||
valid: false,
|
||||
errors: [{
|
||||
message: error.message,
|
||||
stack: error.stack
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
export default validateJSON;
|
||||
@@ -1,21 +0,0 @@
|
||||
let ajvInstance;
|
||||
|
||||
async function validateJSON(data, schema) {
|
||||
if (!ajvInstance) {
|
||||
const { default: Ajv } = await import('https://cdn.skypack.dev/ajv@8');
|
||||
ajvInstance = new Ajv({ allErrors: true });
|
||||
}
|
||||
const ajv = ajvInstance;
|
||||
try {
|
||||
const validate = ajv.compile(schema);
|
||||
const valid = validate(data);
|
||||
const errors = valid ? [] : ajv.errorsText(validate.errors, { separator: '\n' })
|
||||
.split('\n')
|
||||
.map(s => s.trim())
|
||||
.filter(Boolean);
|
||||
return { valid, errors };
|
||||
} catch (e) {
|
||||
return { valid: false, errors: [`Schema error: ${e.message}`] };
|
||||
}
|
||||
}
|
||||
export default validateJSON;
|
||||
@@ -1,10 +0,0 @@
|
||||
async function validateJSON(data,schema){
|
||||
const{default:Ajv}=await import('https://esm.sh/ajv@7.13.4');
|
||||
const ajv=new Ajv({allErrors:true});
|
||||
const validate=ajv.compile(schema);
|
||||
const valid=validate(data);
|
||||
if(valid)return{valid:true,errors:[]};
|
||||
const errors=validate.errors.map(e=>`${e.instancePath||''} ${e.message||'Validation error'}`.trim()).filter(Boolean);
|
||||
return{valid:false,errors};
|
||||
}
|
||||
export default validateJSON;
|
||||
13
tests/8_json_validator/outputs/x-ai_grok-4.js
Normal file
13
tests/8_json_validator/outputs/x-ai_grok-4.js
Normal file
@@ -0,0 +1,13 @@
|
||||
async function validateJSON(data, schema) {
|
||||
const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8/dist/ajv.min.js');
|
||||
const ajv = new Ajv({ allErrors: true });
|
||||
const validate = ajv.compile(schema);
|
||||
const valid = validate(data);
|
||||
return {
|
||||
valid,
|
||||
errors: valid ? [] : validate.errors.map(e => e.message)
|
||||
};
|
||||
}
|
||||
export default validateJSON;
|
||||
// Generation time: 16.498s
|
||||
// Result: FAIL
|
||||
@@ -25,4 +25,6 @@ async function createStreamVisualizer(asyncIterable, options) {
|
||||
|
||||
return { data, path };
|
||||
}
|
||||
export default createStreamVisualizer;
|
||||
export default createStreamVisualizer;
|
||||
// Generation time: 5.230s
|
||||
// Result: PASS
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user