diff --git a/results.json b/results.json index 530e230..5ad0582 100644 --- a/results.json +++ b/results.json @@ -1,32 +1,42 @@ { "openai/gpt-5.1-codex": { - "1_dijkstra": 12.73643722, - "2_convex_hull": 20.551442495, - "3_lis": 6.9065933989999975, - "4_determinant": 3.340895964000003, - "5_markdown_parser": 3.5223763349999935, - "6_csv_processor": 16.396112775000002, - "7_scheduler": 85.407877246, - "8_json_validator": 9.581871734999993 + "1_dijkstra": null, + "2_convex_hull": null, + "3_lis": 4.134811772999999, + "4_determinant": 3.128456531999999, + "5_markdown_parser": 2.4388916820000004, + "6_csv_processor": 43.478935838999995, + "7_scheduler": 84.317196593, + "8_json_validator": 6.765057070999989 + }, + "openai/gpt-5.1-chat": { + "1_dijkstra": null, + "2_convex_hull": 4.03333652099999, + "3_lis": 3.2548832980000006, + "4_determinant": 3.480435989999998, + "5_markdown_parser": 12.157845766999992, + "6_csv_processor": null, + "7_scheduler": 3.6146848039999897, + "8_json_validator": 3.9886151490000192 }, "google/gemini-2.5-pro": { - "1_dijkstra": 52.880149714, - "2_convex_hull": 53.18372889399997, - "3_lis": 28.706411030000016, - "4_determinant": 12.91266780300002, - "5_markdown_parser": 19.207484959000023, - "6_csv_processor": 37.37156615500001, - "7_scheduler": 108.64825142700003, - "8_json_validator": 25.360757163000002 + "1_dijkstra": 44.864160204000015, + "2_convex_hull": 33.892027145, + "3_lis": 36.906535906, + "4_determinant": 11.497210719000025, + "5_markdown_parser": 13.62311761299998, + "6_csv_processor": 42.61058959099999, + "7_scheduler": 12.12732526100002, + "8_json_validator": 50.54006011399999 }, "anthropic/claude-sonnet-4.5 TEMP:0.7": { - "1_dijkstra": 3.8821057339999823, - "2_convex_hull": 4.63132335000002, - "3_lis": 2.5366414799999912, - "4_determinant": 1.642024412000028, - "5_markdown_parser": 2.235130207999959, - "6_csv_processor": 4.568896986000007, - "7_scheduler": 15.728725427000084, - "8_json_validator": 3.0146192130000564 + "1_dijkstra": 4.8069697199999935, + "2_convex_hull": 4.475060508999974, + "3_lis": 2.835424330000009, + "4_determinant": 2.3172859399999726, + "5_markdown_parser": 2.080127800999966, + "6_csv_processor": 5.218456623000034, + "7_scheduler": 11.33699588100001, + "8_json_validator": 3.298284380999976 } } \ No newline at end of file diff --git a/tests/1_dijkstra/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/1_dijkstra/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index f249712..de03834 100644 --- a/tests/1_dijkstra/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/1_dijkstra/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -1,21 +1,24 @@ async function findShortestPath(graph, start, end) { - const { default: PriorityQueue } = await import('https://cdn.skypack.dev/js-priority-queue'); + const { default: PQ } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@0.1.5/+esm'); - const distances = {}; - const pq = new PriorityQueue({ comparator: (a, b) => a.dist - b.dist }); - - for (const node in graph) distances[node] = Infinity; + const distances = Object.keys(graph).reduce((acc, node) => ({ ...acc, [node]: Infinity }), {}); distances[start] = 0; + + const pq = new PQ({ comparator: (a, b) => a.dist - b.dist }); pq.queue({ node: start, dist: 0 }); + const visited = new Set(); + while (pq.length) { const { node, dist } = pq.dequeue(); - if (node === end) return dist; - if (dist > distances[node]) continue; + if (visited.has(node)) continue; + visited.add(node); - for (const neighbor in graph[node]) { - const newDist = dist + graph[node][neighbor]; + 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 }); diff --git a/tests/1_dijkstra/outputs/google_gemini-2.5-pro.js b/tests/1_dijkstra/outputs/google_gemini-2.5-pro.js index 87a7a80..a6c489c 100644 --- a/tests/1_dijkstra/outputs/google_gemini-2.5-pro.js +++ b/tests/1_dijkstra/outputs/google_gemini-2.5-pro.js @@ -1,33 +1,33 @@ -async function findShortestPath(graph, startNode, endNode) { - const { default: PriorityQueue } = await import('https://esm.sh/js-priority-queue'); +async function findShortestPath(graph, start, end) { + const { default: PriorityQueue } = await import('https://cdn.jsdelivr.net/npm/js-priority-queue@0.1.5/priority-queue.min.js'); - const distances = { [startNode]: 0 }; - const queue = new PriorityQueue({ comparator: (a, b) => a.priority - b.priority }); + const distances = Object.fromEntries( + Object.keys(graph).map(node => [node, Infinity]) + ); + distances[start] = 0; - queue.queue({ node: startNode, priority: 0 }); + const pq = new PriorityQueue({ + comparator: (a, b) => distances[b] - distances[a] + }); + pq.queue(start); - while (queue.length) { - const { node: currentNode, priority: currentDist } = queue.dequeue(); + while (pq.length) { + const currentNode = pq.dequeue(); - if (currentDist > (distances[currentNode] ?? Infinity)) { - continue; - } + if (currentNode === end) break; - if (currentNode === endNode) { - return currentDist; - } + if (!graph[currentNode]) continue; - for (const neighbor in graph[currentNode] || {}) { - const weight = graph[currentNode][neighbor]; - const newDist = currentDist + weight; + for (const [neighbor, weight] of Object.entries(graph[currentNode])) { + const newDist = distances[currentNode] + weight; - if (newDist < (distances[neighbor] ?? Infinity)) { + if (newDist < distances[neighbor]) { distances[neighbor] = newDist; - queue.queue({ node: neighbor, priority: newDist }); + pq.queue(neighbor); } } } - return Infinity; + return distances[end]; } export default findShortestPath; \ No newline at end of file diff --git a/tests/1_dijkstra/outputs/openai_gpt-5.1-codex.js b/tests/1_dijkstra/outputs/openai_gpt-5.1-codex.js deleted file mode 100644 index d20ab5e..0000000 --- a/tests/1_dijkstra/outputs/openai_gpt-5.1-codex.js +++ /dev/null @@ -1,19 +0,0 @@ -async function findShortestPath(g,s,e){ - const {default:Q}=await import('https://cdn.skypack.dev/js-priority-queue') - const d={[s]:0},q=new Q({comparator:(a,b)=>a.w-b.w}) - q.queue({n:s,w:0}) - while(q.length){ - const {n,w}=q.dequeue() - if(w>(d[n]??Infinity))continue - if(n===e)return w - for(const k in g[n]||{}){ - const nw=w+g[n][k] - if(nw<(d[k]??Infinity)){ - d[k]=nw - q.queue({n:k,w:nw}) - } - } - } - return Infinity -} -export default findShortestPath; \ No newline at end of file diff --git a/tests/2_convex_hull/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/2_convex_hull/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index 9c4ac7d..9a7b132 100644 --- a/tests/2_convex_hull/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/2_convex_hull/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -21,6 +21,6 @@ async function findConvexHull(points) { return hull; }; - return [...buildHull(sorted), ...buildHull(sorted.slice().reverse())]; + return [...buildHull(sorted), ...buildHull([...sorted].reverse())]; } export default findConvexHull; \ No newline at end of file diff --git a/tests/2_convex_hull/outputs/google_gemini-2.5-pro.js b/tests/2_convex_hull/outputs/google_gemini-2.5-pro.js index 9abeb1f..00f59ee 100644 --- a/tests/2_convex_hull/outputs/google_gemini-2.5-pro.js +++ b/tests/2_convex_hull/outputs/google_gemini-2.5-pro.js @@ -1,27 +1,29 @@ -async function findConvexHull(points) { - const { sortBy, uniqWith, isEqual } = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.min.js'); +const findConvexHull = async (points) => { + const _ = await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.min.js'); - const uniquePoints = uniqWith(points, isEqual); - if (uniquePoints.length < 3) { - return uniquePoints; + const sortedPoints = _.sortBy(_.uniqWith(points, _.isEqual), ['x', 'y']); + + if (sortedPoints.length < 3) { + return sortedPoints; } - const sortedPoints = sortBy(uniquePoints, ['x', 'y']); - const crossProduct = (p1, p2, p3) => (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x); - const buildHull = pts => pts.reduce((hull, p) => { - while (hull.length >= 2 && crossProduct(hull.at(-2), hull.at(-1), p) <= 0) { - hull.pop(); + const buildHalfHull = (pointSet) => { + const hull = []; + for (const p of pointSet) { + while (hull.length >= 2 && crossProduct(hull.at(-2), hull.at(-1), p) <= 0) { + hull.pop(); + } + hull.push(p); } - hull.push(p); return hull; - }, []); + }; - const lower = buildHull(sortedPoints); - const upper = buildHull([...sortedPoints].reverse()); + const lower = buildHalfHull(sortedPoints); + const upper = buildHalfHull([...sortedPoints].reverse()); return [...lower.slice(0, -1), ...upper.slice(0, -1)]; -} +}; export default findConvexHull; \ No newline at end of file diff --git a/tests/2_convex_hull/outputs/openai_gpt-5.1-chat.js b/tests/2_convex_hull/outputs/openai_gpt-5.1-chat.js new file mode 100644 index 0000000..9d0520f --- /dev/null +++ b/tests/2_convex_hull/outputs/openai_gpt-5.1-chat.js @@ -0,0 +1,20 @@ +export async function findConvexHull(a){ + const _ = (await import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.min.js')).default + a = _.uniqWith(a,_.isEqual) + a = _.sortBy(a,['x','y']) + const c=(o,p,q)=>((p.x-o.x)*(q.y-o.y)-(p.y-o.y)*(q.x-o.x)) + const b=[] + for(const p of a){ + while(b.length>1 && c(b[b.length-2],b[b.length-1],p)<=0) b.pop() + b.push(p) + } + const u=[] + for(const p of [...a].reverse()){ + while(u.length>1 && c(u[u.length-2],u[u.length-1],p)<=0) u.pop() + u.push(p) + } + u.pop() + b.pop() + return [...b,...u] +} +export default findConvexHull; \ No newline at end of file diff --git a/tests/2_convex_hull/outputs/openai_gpt-5.1-codex.js b/tests/2_convex_hull/outputs/openai_gpt-5.1-codex.js deleted file mode 100644 index e5d313f..0000000 --- a/tests/2_convex_hull/outputs/openai_gpt-5.1-codex.js +++ /dev/null @@ -1,23 +0,0 @@ -let cache -const loader=()=>cache??=import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/lodash.js') - -export const findConvexHull=async pts=>{ - const {sortBy:s,uniqWith:u,isEqual:e}=await loader() - const data=u(s(pts,[v=>v.x,v=>v.y]),e) - if(data.length<2)return data.slice() - const cross=(o,a,b)=>(a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x) - const lower=[],upper=[] - for(const p of data){ - while(lower.length>1&&cross(lower.at(-2),lower.at(-1),p)<=0)lower.pop() - lower.push(p) - } - for(let i=data.length;i--;){ - const p=data[i] - while(upper.length>1&&cross(upper.at(-2),upper.at(-1),p)<=0)upper.pop() - upper.push(p) - } - lower.pop() - upper.pop() - return lower.concat(upper) -} -export default findConvexHull; \ No newline at end of file diff --git a/tests/3_lis/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/3_lis/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index d66502e..3e87752 100644 --- a/tests/3_lis/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/3_lis/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -1,13 +1,13 @@ const findLISLength = async (arr) => { - const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm'); - if (!arr?.length) return 0; + const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm'); + const tails = []; for (const num of arr) { - const idx = bisectLeft(tails, num); - tails[idx] = num; + const pos = bisectLeft(tails, num); + tails[pos] = num; } return tails.length; diff --git a/tests/3_lis/outputs/google_gemini-2.5-pro.js b/tests/3_lis/outputs/google_gemini-2.5-pro.js index e6ea665..304fe96 100644 --- a/tests/3_lis/outputs/google_gemini-2.5-pro.js +++ b/tests/3_lis/outputs/google_gemini-2.5-pro.js @@ -1,16 +1,12 @@ -const findLISLength = async (nums) => { - if (!nums?.length) { - return 0; - } - - const { bisectLeft } = await import('https://esm.sh/d3-array'); +async function findLISLength(nums) { + const { bisectLeft } = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm'); const tails = []; - for (const num of nums) { + for (const num of nums || []) { tails[bisectLeft(tails, num)] = num; } return tails.length; -}; +} export default findLISLength; \ No newline at end of file diff --git a/tests/3_lis/outputs/openai_gpt-5.1-chat.js b/tests/3_lis/outputs/openai_gpt-5.1-chat.js new file mode 100644 index 0000000..9200c26 --- /dev/null +++ b/tests/3_lis/outputs/openai_gpt-5.1-chat.js @@ -0,0 +1,10 @@ +async function findLISLength(a) { + const {bisectLeft:b} = await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm') + const t = [] + for (const x of a) { + const i = b(t, x) + t[i] = x + } + return t.length +} +export default findLISLength; \ No newline at end of file diff --git a/tests/3_lis/outputs/openai_gpt-5.1-codex.js b/tests/3_lis/outputs/openai_gpt-5.1-codex.js index 8d1d0de..4ece4d6 100644 --- a/tests/3_lis/outputs/openai_gpt-5.1-codex.js +++ b/tests/3_lis/outputs/openai_gpt-5.1-codex.js @@ -1,9 +1,10 @@ -const m = import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm'); - -async function findLISLength(nums) { - const { bisectLeft: b } = await m; - const tails = []; - for (const n of nums) tails[b(tails, n)] = n; - return tails.length; +async function findLISLength(nums){ + const {bisectLeft}=await import('https://cdn.jsdelivr.net/npm/d3-array@3/+esm') + const tails=[] + for(const n of nums){ + const i=bisectLeft(tails,n) + tails[i]=n + } + return tails.length } export default findLISLength; \ No newline at end of file diff --git a/tests/4_determinant/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/4_determinant/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index 58e14ae..020003b 100644 --- a/tests/4_determinant/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/4_determinant/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -1,5 +1,5 @@ -const calculateDeterminant = async (matrix) => { +async function calculateDeterminant(matrix) { const { det } = await import('https://cdn.jsdelivr.net/npm/mathjs@11.11.0/+esm'); return det(matrix); -}; +} export default calculateDeterminant; \ No newline at end of file diff --git a/tests/4_determinant/outputs/google_gemini-2.5-pro.js b/tests/4_determinant/outputs/google_gemini-2.5-pro.js index f8a1a02..9019d30 100644 --- a/tests/4_determinant/outputs/google_gemini-2.5-pro.js +++ b/tests/4_determinant/outputs/google_gemini-2.5-pro.js @@ -1,5 +1,5 @@ -const calculateDeterminant = async m => { - const { det } = await import('https://cdn.jsdelivr.net/npm/mathjs/+esm'); - return det(m); +const calculateDeterminant = async matrix => { + const { det } = await import('https://cdn.jsdelivr.net/npm/mathjs@12.4.2/es/index.js'); + return det(matrix); }; export default calculateDeterminant; \ No newline at end of file diff --git a/tests/4_determinant/outputs/openai_gpt-5.1-chat.js b/tests/4_determinant/outputs/openai_gpt-5.1-chat.js new file mode 100644 index 0000000..9908892 --- /dev/null +++ b/tests/4_determinant/outputs/openai_gpt-5.1-chat.js @@ -0,0 +1,5 @@ +async function calculateDeterminant(m){ + const {det}=await import('https://cdn.jsdelivr.net/npm/mathjs@11.11.0/+esm') + return det(m) +} +export default calculateDeterminant; \ No newline at end of file diff --git a/tests/4_determinant/outputs/openai_gpt-5.1-codex.js b/tests/4_determinant/outputs/openai_gpt-5.1-codex.js index fca5b94..9908892 100644 --- a/tests/4_determinant/outputs/openai_gpt-5.1-codex.js +++ b/tests/4_determinant/outputs/openai_gpt-5.1-codex.js @@ -1,5 +1,5 @@ -export const calculateDeterminant = async matrix => { - const { det } = await import('https://cdn.jsdelivr.net/npm/mathjs@11.11.0/+esm'); - return det(matrix); -}; +async function calculateDeterminant(m){ + const {det}=await import('https://cdn.jsdelivr.net/npm/mathjs@11.11.0/+esm') + return det(m) +} export default calculateDeterminant; \ No newline at end of file diff --git a/tests/5_markdown_parser/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/5_markdown_parser/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index 9bf74ee..41ba4bb 100644 --- a/tests/5_markdown_parser/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/5_markdown_parser/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -1,5 +1,5 @@ -const parseMarkdown = async (md) => { - const { marked } = await import('https://cdn.jsdelivr.net/npm/marked@11.1.1/+esm'); +async function parseMarkdown(md) { + const { marked } = await import('https://cdn.jsdelivr.net/npm/marked@11/+esm'); return marked.parse(md); -}; +} export default parseMarkdown; \ No newline at end of file diff --git a/tests/5_markdown_parser/outputs/google_gemini-2.5-pro.js b/tests/5_markdown_parser/outputs/google_gemini-2.5-pro.js index 482d179..62477fb 100644 --- a/tests/5_markdown_parser/outputs/google_gemini-2.5-pro.js +++ b/tests/5_markdown_parser/outputs/google_gemini-2.5-pro.js @@ -1,5 +1,6 @@ const parseMarkdown = async (md) => { - const { marked } = await import('https://cdn.jsdelivr.net/npm/marked@12.0.2/+esm'); + const cdn = 'https://cdn.jsdelivr.net/npm/marked@13.0.0/lib/marked.esm.js'; + const { marked } = await import(cdn); return marked.parse(md); }; export default parseMarkdown; \ No newline at end of file diff --git a/tests/5_markdown_parser/outputs/openai_gpt-5.1-chat.js b/tests/5_markdown_parser/outputs/openai_gpt-5.1-chat.js new file mode 100644 index 0000000..00db97f --- /dev/null +++ b/tests/5_markdown_parser/outputs/openai_gpt-5.1-chat.js @@ -0,0 +1,2 @@ + +export default parseMarkdown; \ No newline at end of file diff --git a/tests/5_markdown_parser/outputs/openai_gpt-5.1-codex.js b/tests/5_markdown_parser/outputs/openai_gpt-5.1-codex.js index b045e3c..d8f9b46 100644 --- a/tests/5_markdown_parser/outputs/openai_gpt-5.1-codex.js +++ b/tests/5_markdown_parser/outputs/openai_gpt-5.1-codex.js @@ -1,7 +1,5 @@ -let m -export const parseMarkdown=async t=>{ - m||(m=import('https://cdn.jsdelivr.net/npm/marked@12.0.2/lib/marked.esm.js')) - const {marked}=await m - return marked.parse(t) +const parseMarkdown = async m => { + const { marked } = await import('https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js') + return marked.parse(m) } export default parseMarkdown; \ No newline at end of file diff --git a/tests/6_csv_processor/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/6_csv_processor/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index 008b93d..2399256 100644 --- a/tests/6_csv_processor/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/6_csv_processor/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -1,14 +1,10 @@ -const processCSV = async (csvString, config) => { - const { parse } = await import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm'); +async function processCSV(csvString, config) { + const { parse } = await import('https://cdn.skypack.dev/papaparse@5.4.1'); - const { data } = parse(csvString, { - header: true, - skipEmptyLines: true, - dynamicTyping: true - }); + const { data } = parse(csvString, { header: true, skipEmptyLines: true }); const filtered = data.filter(row => - row[config.filterColumn] == config.filterValue + String(row[config.filterColumn]) === String(config.filterValue) ); const grouped = filtered.reduce((acc, row) => { @@ -18,15 +14,19 @@ const processCSV = async (csvString, config) => { return acc; }, {}); - const operations = { - sum: arr => arr.reduce((s, r) => s + (Number(r[config.aggregateColumn]) || 0), 0), - avg: arr => operations.sum(arr) / arr.length || 0, - count: arr => arr.length - }; - - return Object.entries(grouped).map(([key, rows]) => ({ - [config.groupBy]: key, - result: operations[config.operation](rows) - })); -}; + return Object.entries(grouped).map(([key, rows]) => { + let result; + const vals = rows.map(r => parseFloat(r[config.aggregateColumn]) || 0); + + if (config.operation === 'sum') { + result = vals.reduce((a, b) => a + b, 0); + } else if (config.operation === 'avg') { + result = vals.reduce((a, b) => a + b, 0) / vals.length; + } else { + result = rows.length; + } + + return { [config.groupBy]: key, result }; + }); +} export default processCSV; \ No newline at end of file diff --git a/tests/6_csv_processor/outputs/google_gemini-2.5-pro.js b/tests/6_csv_processor/outputs/google_gemini-2.5-pro.js index 8c2e4a1..ed2244b 100644 --- a/tests/6_csv_processor/outputs/google_gemini-2.5-pro.js +++ b/tests/6_csv_processor/outputs/google_gemini-2.5-pro.js @@ -1,4 +1,4 @@ -const processCSV = async (csvString, config) => { +async function processCSV(csvString, config) { const { filterColumn, filterValue, @@ -7,32 +7,38 @@ const processCSV = async (csvString, config) => { operation, } = config; - const [Papa, _] = await Promise.all([ - import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm'), - import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/+esm'), - ]); + const { default: Papa } = await import('https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.4.1/papaparse.min.js'); + + const { data } = Papa.parse(csvString, { + header: true, + dynamicTyping: true, + skipEmptyLines: true, + }); const aggregators = { - sum: items => _.sumBy(items, aggregateColumn), - count: items => items.length, - avg: items => _.sumBy(items, aggregateColumn) / items.length || 0, + sum: (acc, val) => (acc || 0) + val, + count: (acc, _val) => (acc || 0) + 1, + avg: (acc, val) => { + const state = acc || { sum: 0, count: 0 }; + state.sum += val; + state.count += 1; + return state; + }, }; - const { data } = await new Promise(resolve => - Papa.parse(csvString, { - header: true, - dynamicTyping: true, - skipEmptyLines: true, - complete: resolve, - }) - ); + const groups = data + .filter(row => row[filterColumn] == filterValue) + .reduce((acc, row) => { + const key = row[groupBy]; + acc[key] = aggregators[operation](acc[key], row[aggregateColumn]); + return acc; + }, {}); - const filteredData = data.filter(row => row[filterColumn] === filterValue); - const groupedData = _.groupBy(filteredData, groupBy); - - return Object.entries(groupedData).map(([key, group]) => ({ - [groupBy]: isNaN(Number(key)) ? key : Number(key), - result: aggregators[operation](group), + return Object.entries(groups).map(([key, value]) => ({ + [groupBy]: key, + result: operation === 'avg' + ? (value.count ? value.sum / value.count : 0) + : value, })); -}; +} export default processCSV; \ No newline at end of file diff --git a/tests/6_csv_processor/outputs/openai_gpt-5.1-codex.js b/tests/6_csv_processor/outputs/openai_gpt-5.1-codex.js index 47484c3..ba7aa9b 100644 --- a/tests/6_csv_processor/outputs/openai_gpt-5.1-codex.js +++ b/tests/6_csv_processor/outputs/openai_gpt-5.1-codex.js @@ -1,16 +1,21 @@ -export const processCSV=async(csv,cfg)=>{ - const [{parse},{groupBy,sumBy}]=await Promise.all([ - import('https://cdn.jsdelivr.net/npm/papaparse@5.4.1/+esm'), - import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/+esm') - ]); - const {filterColumn:fc,filterValue:fv,groupBy:gb,aggregateColumn:ac,operation:op}=cfg; - const rows=parse(csv,{header:!0,skipEmptyLines:!0}).data.filter(r=>r[fc]==fv); - const grouped=groupBy(rows,r=>r[gb]); - const agg=v=>{ - if(op=='count')return v.length; - const total=sumBy(v,x=>+x[ac]||0); - return op=='avg'&&v.length?total/v.length:total; - }; - return Object.entries(grouped).map(([k,v])=>({[gb]:k,result:agg(v)})); -}; +const libs=(()=>{let c;return()=>c||(c=Promise.all([ +import('https://cdn.jsdelivr.net/npm/d3-dsv@3/+esm'), +import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.21/groupBy.js') +]).then(([dsv,gb])=>({parse:dsv.csvParse,groupBy:gb.default||gb})));})(); + +const toNum=v=>{const n=+v;return Number.isFinite(n)?n:0}; + +async function processCSV(csv,opts){ + const {parse,groupBy}=await libs(); + const rows=parse(csv); + const {filterColumn:fc,filterValue:fv,groupBy:gc,aggregateColumn:ac,operation:op}=opts; + const pool=groupBy(rows.filter(r=>r[fc]==fv),r=>r[gc]??''); + const calc={ + sum:x=>x.reduce((t,r)=>t+toNum(r[ac]),0), + avg:x=>x.length?x.reduce((t,r)=>t+toNum(r[ac]),0)/x.length:0, + count:x=>x.length + }[op]; + if(!calc) throw new Error('Unsupported operation'); + return Object.entries(pool).map(([k,x])=>({[gc]:k,result:calc(x)})); +} export default processCSV; \ No newline at end of file diff --git a/tests/7_scheduler/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js b/tests/7_scheduler/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js index 6a07541..8b530e9 100644 --- a/tests/7_scheduler/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js +++ b/tests/7_scheduler/outputs/anthropic_claude-sonnet-4.5 TEMP_0.7.js @@ -1,23 +1,22 @@ const findAvailableSlots = async (cal1, cal2, constraints) => { const { default: dayjs } = await import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/+esm'); - const [{ default: utc }, { default: customParseFormat }, { default: isBetween }] = await Promise.all([ - import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/utc.js'), - import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/customParseFormat.js'), - import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/isBetween.js') + const [{ default: utc }, { default: isBetween }] = await Promise.all([ + import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/utc.js/+esm'), + import('https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/isBetween.js/+esm') ]); dayjs.extend(utc); - dayjs.extend(customParseFormat); dayjs.extend(isBetween); const { durationMinutes, searchRange, workHours } = constraints; - const allBusy = [...cal1, ...cal2].map(s => ({ - start: dayjs(s.start), - end: dayjs(s.end) - })).sort((a, b) => a.start - b.start); - - const merged = allBusy.reduce((acc, curr) => { - if (!acc.length || acc[acc.length - 1].end < curr.start) { + const [whStart, whEnd] = [workHours.start.split(':'), workHours.end.split(':')]; + + const merged = [...cal1, ...cal2] + .map(s => ({ start: dayjs(s.start), end: dayjs(s.end) })) + .sort((a, b) => a.start - b.start); + + const busy = merged.reduce((acc, curr) => { + if (!acc.length || curr.start > acc[acc.length - 1].end) { acc.push(curr); } else { acc[acc.length - 1].end = dayjs.max(acc[acc.length - 1].end, curr.end); @@ -26,81 +25,45 @@ const findAvailableSlots = async (cal1, cal2, constraints) => { }, []); const slots = []; - const searchStart = dayjs(searchRange.start); - const searchEnd = dayjs(searchRange.end); - const [whStart, whEnd] = [ - dayjs(workHours.start, 'HH:mm'), - dayjs(workHours.end, 'HH:mm') - ]; + let current = dayjs(searchRange.start); + const rangeEnd = dayjs(searchRange.end); - const isInWorkHours = (dt) => { - const time = dayjs().hour(dt.hour()).minute(dt.minute()); - return time.isBetween(whStart, whEnd, null, '[)'); - }; - - const addSlot = (start, end) => { - let curr = start; - while (curr.add(durationMinutes, 'minute') <= end) { - if (isInWorkHours(curr) && isInWorkHours(curr.add(durationMinutes, 'minute').subtract(1, 'second'))) { - const slotEnd = curr.add(durationMinutes, 'minute'); - const dayEnd = curr.hour(whEnd.hour()).minute(whEnd.minute()); - if (slotEnd <= dayEnd) { - slots.push({ - start: curr.toISOString(), - end: slotEnd.toISOString() - }); - } - } - curr = curr.add(15, 'minute'); - } - }; - - let prevEnd = searchStart.hour(whStart.hour()).minute(whStart.minute()); - if (prevEnd < searchStart) prevEnd = searchStart; - - merged.forEach(busy => { - if (busy.start > prevEnd) { - let gapStart = prevEnd; - let gapEnd = busy.start; + while (current < rangeEnd) { + const dayStart = current.hour(+whStart[0]).minute(+whStart[1]).second(0); + const dayEnd = current.hour(+whEnd[0]).minute(+whEnd[1]).second(0); + + let slotStart = dayStart < current ? current : dayStart; + + for (const b of busy) { + if (b.end <= slotStart || b.start >= dayEnd) continue; - let day = gapStart.startOf('day'); - while (day <= gapEnd) { - const dayStart = dayjs.max( - gapStart, - day.hour(whStart.hour()).minute(whStart.minute()) - ); - const dayEnd = dayjs.min( - gapEnd, - day.hour(whEnd.hour()).minute(whEnd.minute()) - ); + if (b.start > slotStart) { + const slotEnd = dayjs.min(b.start, dayEnd); + let probe = slotStart; - if (dayStart < dayEnd && dayStart >= searchStart && dayEnd <= searchEnd) { - addSlot(dayStart, dayEnd); + while (probe.add(durationMinutes, 'minute') <= slotEnd) { + slots.push({ + start: probe.toISOString(), + end: probe.add(durationMinutes, 'minute').toISOString() + }); + probe = probe.add(durationMinutes, 'minute'); } - day = day.add(1, 'day'); + } + slotStart = dayjs.max(slotStart, b.end); + } + + if (slotStart < dayEnd) { + let probe = slotStart; + while (probe.add(durationMinutes, 'minute') <= dayEnd) { + slots.push({ + start: probe.toISOString(), + end: probe.add(durationMinutes, 'minute').toISOString() + }); + probe = probe.add(durationMinutes, 'minute'); } } - prevEnd = dayjs.max(prevEnd, busy.end); - }); - - const finalEnd = searchEnd.hour(whEnd.hour()).minute(whEnd.minute()); - if (prevEnd < finalEnd) { - let day = prevEnd.startOf('day'); - while (day <= finalEnd) { - const dayStart = dayjs.max( - prevEnd, - day.hour(whStart.hour()).minute(whStart.minute()) - ); - const dayEnd = dayjs.min( - finalEnd, - day.hour(whEnd.hour()).minute(whEnd.minute()) - ); - - if (dayStart < dayEnd && dayStart >= searchStart && dayEnd <= searchEnd) { - addSlot(dayStart, dayEnd); - } - day = day.add(1, 'day'); - } + + current = current.add(1, 'day').startOf('day'); } return slots; diff --git a/tests/7_scheduler/outputs/google_gemini-2.5-pro.js b/tests/7_scheduler/outputs/google_gemini-2.5-pro.js index aecbca3..2cb0879 100644 --- a/tests/7_scheduler/outputs/google_gemini-2.5-pro.js +++ b/tests/7_scheduler/outputs/google_gemini-2.5-pro.js @@ -1,69 +1,2 @@ -async function findAvailableSlots(cal1, cal2, c) { - const { - parseISO, formatISO, addMinutes, isAfter, max, startOfDay, - setHours, setMinutes, setSeconds, setMilliseconds, eachDayOfInterval - } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.6.0/index.mjs'); - const { durationMinutes: dur, searchRange: sr, workHours: wh } = c; - const sStart = parseISO(sr.start); - const sEnd = parseISO(sr.end); - const toDate = s => parseISO(s); - - const [whsH, whsM] = wh.start.split(':').map(Number); - const [wheH, wheM] = wh.end.split(':').map(Number); - - const applyTime = (d, h, m) => - setMilliseconds(setSeconds(setMinutes(setHours(startOfDay(d), h), m), 0), 0); - - const busy = [...cal1, ...cal2].map(({ start, end }) => ({ - start: toDate(start), - end: toDate(end), - })); - - const nonWork = []; - if (sStart < sEnd) { - for (const day of eachDayOfInterval({ start: sStart, end: sEnd })) { - nonWork.push({ - start: startOfDay(day), - end: applyTime(day, whsH, whsM) - }); - nonWork.push({ - start: applyTime(day, wheH, wheM), - end: addMinutes(startOfDay(day), 1440) - }); - } - } - - const unavailable = [...busy, ...nonWork].sort((a, b) => a.start - b.start); - - const merged = unavailable.reduce((acc, slot) => { - const last = acc[acc.length - 1]; - if (last && slot.start <= last.end) { - last.end = max(last.end, slot.end); - } else { - acc.push({ ...slot }); - } - return acc; - }, []); - - const results = []; - let ptr = sStart; - const allBlocks = [...merged, { start: sEnd, end: sEnd }]; - - for (const block of allBlocks) { - let slotStart = ptr; - while (true) { - const slotEnd = addMinutes(slotStart, dur); - if (isAfter(slotEnd, block.start)) break; - results.push({ start: slotStart, end: slotEnd }); - slotStart = slotEnd; - } - ptr = max(ptr, block.end); - } - - return results.map(({ start, end }) => ({ - start: formatISO(start), - end: formatISO(end), - })); -} export default findAvailableSlots; \ No newline at end of file diff --git a/tests/7_scheduler/outputs/openai_gpt-5.1-chat.js b/tests/7_scheduler/outputs/openai_gpt-5.1-chat.js new file mode 100644 index 0000000..c330862 --- /dev/null +++ b/tests/7_scheduler/outputs/openai_gpt-5.1-chat.js @@ -0,0 +1,50 @@ +async function findAvailableSlots(a,b,c){ + const d=await import('https://esm.sh/date-fns@3.6.0') + const {parseISO,formatISO,max,min,addMinutes,isBefore}=d + const p=t=>parseISO(t) + const wh=(dt,s)=>{ + const [H,M]=s.split(':') + const x=new Date(dt) + x.setHours(H,M,0,0) + return x + } + const rng=[p(c.searchRange.start),p(c.searchRange.end)] + const dur=c.durationMinutes + const norm=x=>x.map(v=>[p(v.start),p(v.end)]) + const A=norm(a),B=norm(b) + const merge=x=>{ + let r=x.sort((x,y)=>x[0]-y[0]),o=[r[0]] + for(let i=1;icur) free.push([cur,busy[i][0]]) + cur=max(cur,busy[i][1]) + }else free.push([s,e]) + } + const out=[] + for(let [s,e]of free){ + s=max(s,rng[0]) + e=min(e,rng[1]) + let ws=wh(s,c.workHours.start) + let we=wh(s,c.workHours.end) + if(ws>we){let t=ws;ws=we;we=t} + let ss=max(s,ws),ee=min(e,we) + while(isBefore(addMinutes(ss,dur),ee)){ + out.push({start:formatISO(ss),end:formatISO(addMinutes(ss,dur))}) + ss=addMinutes(ss,dur) + } + } + return out +} +export default findAvailableSlots; \ No newline at end of file diff --git a/tests/7_scheduler/outputs/openai_gpt-5.1-codex.js b/tests/7_scheduler/outputs/openai_gpt-5.1-codex.js index 20b61ca..65332b9 100644 --- a/tests/7_scheduler/outputs/openai_gpt-5.1-codex.js +++ b/tests/7_scheduler/outputs/openai_gpt-5.1-codex.js @@ -1,59 +1,55 @@ -const findAvailableSlots = async (a, b, o) => { - const { parseISO, formatISO, addDays, startOfDay } = await import('https://cdn.skypack.dev/date-fns@2.30.0'); - const dur = o.durationMinutes * 6e4; - const rng = [parseISO(o.searchRange.start), parseISO(o.searchRange.end)]; - const split = t => t.split(':').map(Number); - const hrs = { s: split(o.workHours.start), e: split(o.workHours.end) }; - const busy = [...a, ...b] - .map(v => ({ start: parseISO(v.start), end: parseISO(v.end) })) - .map(v => { - const s = new Date(Math.max(v.start, rng[0])); - const e = new Date(Math.min(v.end, rng[1])); - return s < e ? { start: s, end: e } : null; - }) - .filter(Boolean) - .sort((x, y) => x.start - y.start) - .reduce((m, v) => { - const last = m[m.length - 1]; - if (!last || v.start > last.end) m.push({ start: new Date(v.start), end: new Date(v.end) }); - else if (v.end > last.end) last.end = new Date(v.end); - return m; - }, []); - const slots = []; - const collect = (s, e) => { - let a = s.getTime(), b = e.getTime(); - while (a + dur <= b) { - const r = a + dur; - slots.push({ start: formatISO(new Date(a)), end: formatISO(new Date(r)) }); - a = r; - } - }; - let idx = 0; - for (let d = startOfDay(rng[0]); d <= rng[1]; d = addDays(d, 1)) { - const ws = new Date(d); - ws.setHours(hrs.s[0], hrs.s[1], 0, 0); - const we = new Date(d); - we.setHours(hrs.e[0], hrs.e[1], 0, 0); - const winStart = new Date(Math.max(ws, rng[0])); - const winEnd = new Date(Math.min(we, rng[1])); - if (winStart >= winEnd) continue; - let cursor = winStart; - while (idx < busy.length && busy[idx].end <= winStart) idx++; - let view = idx; - let done = false; - while (view < busy.length && busy[view].start < winEnd) { - const gapEnd = new Date(Math.min(busy[view].start, winEnd)); - if (gapEnd > cursor) collect(cursor, gapEnd); - cursor = new Date(Math.max(cursor, busy[view].end)); - if (cursor >= winEnd) { - done = true; - break; - } - view++; - } - if (!done && cursor < winEnd) collect(cursor, winEnd); - idx = view; +const luxon=import('https://cdn.skypack.dev/luxon'); + +const findAvailableSlots=async(c1,c2,k)=>{ + const {DateTime}=await luxon; + const {durationMinutes:d,searchRange:r,workHours:w}=k; + const zone=DateTime.fromISO(r.start).zoneName; + const iso=v=>DateTime.fromISO(v,{zone}); + const rangeStart=iso(r.start); + const rangeEnd=iso(r.end); + if(rangeEnd<=rangeStart)return[]; + const [hs,ms]=w.start.split(':').map(Number); + const [he,me]=w.end.split(':').map(Number); + const daysEnd=rangeEnd.startOf('day'); + const windows=[]; + for(let day=rangeStart.startOf('day');day<=daysEnd;day=day.plus({days:1})){ + let s=day.set({hour:hs,minute:ms,second:0,millisecond:0}); + let e=day.set({hour:he,minute:me,second:0,millisecond:0}); + if(e<=s||e<=rangeStart||s>=rangeEnd)continue; + if(srangeEnd)e=rangeEnd; + windows.push({start:s,end:e}); } - return slots; + if(!windows.length)return[]; + const busy=[...c1,...c2].map(v=>{ + let s=iso(v.start),e=iso(v.end); + if(e<=s||e<=rangeStart||s>=rangeEnd)return null; + if(srangeEnd)e=rangeEnd; + return{start:s,end:e}; + }).filter(Boolean).sort((a,b)=>a.start.valueOf()-b.start.valueOf()); + const merged=[]; + for(const slot of busy){ + const last=merged[merged.length-1]; + if(last&&slot.start<=last.end){ + if(slot.end>last.end)last.end=slot.end; + }else merged.push({start:slot.start,end:slot.end}); + } + const out=[]; + const push=(s,e)=>e.diff(s,'minutes').minutes>=d&&out.push({start:s.toISO(),end:e.toISO()}); + for(const wSlot of windows){ + let cur=wSlot.start; + for(const b of merged){ + if(b.start>=wSlot.end)break; + if(b.end<=wSlot.start)continue; + const bs=b.start>wSlot.start?b.start:wSlot.start; + const be=b.endcur)push(cur,bs); + if(be>cur)cur=be; + if(cur>=wSlot.end)break; + } + if(cur { - const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8.12.0/dist/2020.min.js'); + const { default: Ajv } = await import('https://cdn.jsdelivr.net/npm/ajv@8/dist/ajv.bundle.js'); const ajv = new Ajv({ allErrors: true, verbose: true }); const validate = ajv.compile(schema); @@ -7,12 +7,9 @@ const validateJSON = async (data, schema) => { return { valid, - errors: valid ? [] : validate.errors.map(e => ({ - path: e.instancePath || '/', - message: e.message, - keyword: e.keyword, - params: e.params - })) + errors: valid ? [] : validate.errors.map(e => + `${e.instancePath || '/'} ${e.message}${e.params ? ': ' + JSON.stringify(e.params) : ''}` + ) }; }; export default validateJSON; \ No newline at end of file diff --git a/tests/8_json_validator/outputs/google_gemini-2.5-pro.js b/tests/8_json_validator/outputs/google_gemini-2.5-pro.js index 6e73173..4bb7be3 100644 --- a/tests/8_json_validator/outputs/google_gemini-2.5-pro.js +++ b/tests/8_json_validator/outputs/google_gemini-2.5-pro.js @@ -1,16 +1,35 @@ -let ajvPromise; +const validateJSON = async (jsonObject, schemaObject) => { + try { + const [{ + default: Ajv + }, { + default: addFormats + }] = await Promise.all([ + import('https://esm.sh/ajv'), + import('https://esm.sh/ajv-formats') + ]); -const validateJSON = async (data, schema) => { - const { default: Ajv } = await (ajvPromise ||= import('https://cdn.jsdelivr.net/npm/ajv@8.12.0/+esm')); + const ajv = new Ajv({ + allErrors: true + }); + addFormats(ajv); - const ajv = new Ajv({ allErrors: true }); - const validate = ajv.compile(schema); - const valid = validate(data); + const validate = ajv.compile(schemaObject); + const valid = validate(jsonObject); - const errors = valid ? [] : validate.errors.map( - e => (`${e.instancePath || 'root'} ${e.message}`).trim() - ); + const errors = valid ? [] : validate.errors.map( + e => `${e.instancePath || ''}: ${e.message}` + ); - return { valid, errors }; + return { + valid, + errors + }; + } catch (e) { + return { + valid: false, + errors: [`Validation setup failed: ${e.message}`] + }; + } }; export default validateJSON; \ No newline at end of file diff --git a/tests/8_json_validator/outputs/openai_gpt-5.1-chat.js b/tests/8_json_validator/outputs/openai_gpt-5.1-chat.js new file mode 100644 index 0000000..6c34e04 --- /dev/null +++ b/tests/8_json_validator/outputs/openai_gpt-5.1-chat.js @@ -0,0 +1,8 @@ +async function validateJSON(o, s) { + const { default: Ajv } = await import('https://esm.sh/ajv@8'); + const a = new Ajv({ allErrors: true }); + const v = a.compile(s); + const ok = v(o); + return { valid: ok, errors: ok ? [] : v.errors.map(e => e.message) }; +} +export default validateJSON; \ No newline at end of file diff --git a/tests/8_json_validator/outputs/openai_gpt-5.1-codex.js b/tests/8_json_validator/outputs/openai_gpt-5.1-codex.js index d92461a..3f0adf3 100644 --- a/tests/8_json_validator/outputs/openai_gpt-5.1-codex.js +++ b/tests/8_json_validator/outputs/openai_gpt-5.1-codex.js @@ -1,10 +1,10 @@ -const ajvP=import('https://cdn.skypack.dev/ajv@8?min').then(m=>m.default||m) -const ajvI=ajvP.then(Ajv=>new Ajv({allErrors:true})) -export async function validateJSON(data,schema){ - const ajv=await ajvI - let validate - try{validate=ajv.compile(schema)}catch(e){return{valid:false,errors:[e.message]}} - const valid=validate(data) - return valid?{valid:true,errors:[]}:{valid:false,errors:validate.errors.map(e=>(e.instancePath||'/')+' '+e.message)} +const validateJSON=async(j,s)=>{ + const{default:Ajv}=await import('https://esm.sh/ajv@8') + const{default:f}=await import('https://esm.sh/ajv-formats@2') + const a=new Ajv({allErrors:1,strict:false}) + f(a) + const v=a.compile(s) + const ok=v(j) + return{valid:ok,errors:ok?[]:(v.errors||[]).map(e=>`${e.instancePath||'/'} ${e.message}`.trim())} } export default validateJSON; \ No newline at end of file