RYP / src /lib /dsaQuestionsClient.ts
Soumya79's picture
Upload 1361 files
f91a684 verified
import type { CodingQuestion } from '@/data/codingQuestions';
import { apiFetch } from '@/lib/authClient';
type DSADifficulty = CodingQuestion['difficulty'];
type StarterCode = CodingQuestion['starterCode'];
export type DSAMongoQuestion = {
id: string;
source?: string;
questionNumber: number;
title: string;
difficulty: string;
category: string;
topics: string[];
companies?: string[];
hint?: string;
problemStatement: string;
examples?: {
input: string;
expectedOutput: string;
explanation?: string;
}[];
constraints?: string[];
};
type DSAQuestionsResponse = {
questions?: DSAMongoQuestion[];
};
const emptyStarterCode: StarterCode = {
javascript: '',
python: '',
cpp: '',
java: '',
go: '',
};
function splitTopLevel(value: string) {
const parts: string[] = [];
let current = '';
let depth = 0;
let quote: '"' | "'" | null = null;
let escaped = false;
for (const char of value) {
if (escaped) {
current += char;
escaped = false;
continue;
}
if (char === '\\') {
current += char;
escaped = true;
continue;
}
if (quote) {
current += char;
if (char === quote) quote = null;
continue;
}
if (char === '"' || char === "'") {
current += char;
quote = char;
continue;
}
if (char === '[' || char === '{' || char === '(') depth += 1;
if (char === ']' || char === '}' || char === ')') depth = Math.max(0, depth - 1);
if (char === ',' && depth === 0) {
parts.push(current.trim());
current = '';
continue;
}
current += char;
}
if (current.trim()) parts.push(current.trim());
return parts;
}
function parseExampleValue(raw: string): unknown {
const value = raw.trim().replace(/^(?:Input|Output):\s*/i, '');
if (!value) return '';
const jsonLike = value
.replace(/\bTrue\b/g, 'true')
.replace(/\bFalse\b/g, 'false')
.replace(/\bNone\b/g, 'null')
.replace(/\bNULL\b/g, 'null')
.replace(/\bnull\b/g, 'null')
.replace(/'/g, '"');
try {
return JSON.parse(jsonLike);
} catch {
if (/^-?\d+(?:\.\d+)?$/.test(value)) return Number(value);
if (/^(true|false)$/i.test(value)) return value.toLowerCase() === 'true';
return value.replace(/^["']|["']$/g, '');
}
}
function parseExampleParams(input: string) {
const value = input.trim().replace(/^Input:\s*/i, '');
if (!value) return [];
const parts = splitTopLevel(value);
const assignments = parts
.map((part) => part.match(/^[A-Za-z_]\w*\s*=\s*([\s\S]+)$/)?.[1])
.filter((part): part is string => Boolean(part));
if (assignments.length > 0) {
return assignments.map(parseExampleValue);
}
return [parseExampleValue(value)];
}
function normalizeDifficulty(value: string): DSADifficulty {
const normalized = value.trim().toLowerCase();
if (normalized === 'medium' || normalized === 'med.') return 'Medium';
if (normalized === 'hard') return 'Hard';
return 'Easy';
}
function formatDSADescription(question: DSAMongoQuestion) {
const sections = [question.problemStatement.trim()].filter(Boolean);
if (question.examples?.length) {
sections.push(
[
'Examples:',
...question.examples.map((example, index) => {
const lines = [`${index + 1}. Input: ${example.input}`];
if (example.expectedOutput) lines.push(` Output: ${example.expectedOutput}`);
if (example.explanation) lines.push(` Explanation: ${example.explanation}`);
return lines.join('\n');
}),
].join('\n'),
);
}
if (question.constraints?.length) {
sections.push(['Constraints:', ...question.constraints.map((constraint) => `- ${constraint}`)].join('\n'));
}
if (question.hint) {
sections.push(`Hint: ${question.hint}`);
}
if (question.companies?.length) {
sections.push(`Asked by: ${question.companies.join(', ')}`);
}
return sections.join('\n\n');
}
function toTestCases(question: DSAMongoQuestion): CodingQuestion['testCases'] {
return (question.examples ?? []).map((example) => ({
input: example.input,
output: example.expectedOutput,
params: parseExampleParams(example.input),
expected: parseExampleValue(example.expectedOutput),
}));
}
export function mapDSAQuestionToCodingQuestion(question: DSAMongoQuestion): CodingQuestion {
return {
id: question.id || `dsa-${question.questionNumber}`,
title: question.title,
difficulty: normalizeDifficulty(question.difficulty),
category: question.category || question.topics?.[0] || 'DSA',
companies: question.companies ?? [],
description: formatDSADescription(question),
starterCode: emptyStarterCode,
testCases: toTestCases(question),
hiddenTestCases: [],
solution: {
javascript: '',
python: '',
cpp: '',
java: '',
go: '',
explanation: question.hint || 'A full solution is not available for this MongoDB question yet.',
},
};
}
export async function fetchDSAQuestions(): Promise<CodingQuestion[]> {
const res = await apiFetch('/api/dsa/questions');
if (!res.ok) {
const text = await res.text();
throw new Error(text.trim() || `Failed to fetch DSA questions (${res.status})`);
}
const data = (await res.json()) as DSAQuestionsResponse;
return (data.questions ?? []).map(mapDSAQuestionToCodingQuestion);
}