diff --git a/frontend/src/components/Questions/QuestionCategories.tsx b/frontend/src/components/Questions/QuestionCategories.tsx index 33335321..ed10058e 100644 --- a/frontend/src/components/Questions/QuestionCategories.tsx +++ b/frontend/src/components/Questions/QuestionCategories.tsx @@ -1,11 +1,11 @@ export const QUESTION_CATEGORIES = [ - "Strings", - "Data Structures", - "Algorithms", + "Algorithm", + "Data Structure", "Array", + "String", "Hash Table", - "Math", "Dynamic Programming", + "Math", "Sorting", "Greedy", "Depth-First Search", @@ -15,19 +15,21 @@ export const QUESTION_CATEGORIES = [ "Tree", "Matrix", "Two Pointers", - "Binary Tree", "Bit Manipulation", + "Binary Tree", "Heap (Priority Queue)", "Stack", "Prefix Sum", "Graph", + "Simulation", + "Design", "Counting", - "Backtracking", "Sliding Window", + "Backtracking", "Union Find", "Linked List", - "Ordered Set", "Enumeration", + "Ordered Set", "Monotonic Stack", "Trie", "Recursion", @@ -36,17 +38,20 @@ export const QUESTION_CATEGORIES = [ "Bitmask", "Queue", "Binary Search Tree", + "Segment Tree", "Memoization", "Geometry", - "Topological Sort", "Binary Indexed Tree", + "Topological Sort", "Game Theory", "Hash Function", - "Shortest Path", "Combinatorics", + "Shortest Path", + "Interactive", "String Matching", "Data Stream", "Rolling Hash", + "Brainteaser", "Randomized", "Monotonic Queue", "Merge Sort", @@ -56,6 +61,15 @@ export const QUESTION_CATEGORIES = [ "Probability and Statistics", "Quickselect", "Bucket Sort", + "Suffix Array", "Minimum Spanning Tree", "Counting Sort", + "Shell", + "Line Sweep", + "Reservoir Sampling", + "Strongly Connected Component", + "Eulerian Circuit", + "Radix Sort", + "Rejection Sampling", + "Biconnected Component" ] \ No newline at end of file diff --git a/frontend/src/components/Questions/QuestionForm.tsx b/frontend/src/components/Questions/QuestionForm.tsx index 06837f49..5be5cbcf 100644 --- a/frontend/src/components/Questions/QuestionForm.tsx +++ b/frontend/src/components/Questions/QuestionForm.tsx @@ -14,6 +14,7 @@ import DialogContent from "@mui/material/DialogContent"; import DialogActions from "@mui/material/DialogActions"; import Snackbar from "@mui/material/Snackbar"; import MuiAlert from "@mui/material/Alert"; +import {parseHtmlDescriptionWithoutExamples} from "../../utils/utils" interface QuestionFormProps { question?: Question; @@ -102,13 +103,16 @@ const QuestionForm: React.FC = ({ const words1 = description1.split(" "); const words2 = description2.split(" "); + const commonWords = words1.filter((word) => words2.includes(word)); - const similarity = commonWords.length / words1.length; + const similarityRatio = commonWords.length / words1.length; + const sharedWordCount = commonWords.length; - return similarity; + return { similarityRatio, sharedWordCount }; } + const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); // Check for empty fields @@ -127,12 +131,14 @@ const QuestionForm: React.FC = ({ // Check for similar questions const similarityThreshold = 0.6; // Adjust as needed + const sharedWordCountThreshold = 20; const similarQuestions = questions.filter((existingQuestion) => { - const similarity = calculateSimilarity( + const { similarityRatio, sharedWordCount } = calculateSimilarity( existingQuestion.description, question.description ); - return similarity >= similarityThreshold; + return (similarityRatio >= similarityThreshold || sharedWordCount >= sharedWordCountThreshold) + && existingQuestion.id !== question.id; }); if (similarQuestions.length > 0) { @@ -144,6 +150,7 @@ const QuestionForm: React.FC = ({ } }; + const handleCloseDialog = () => { setShowSimilarQuestionsDialog(false); }; @@ -373,8 +380,8 @@ const QuestionForm: React.FC = ({ {similarQuestions.map((similarQuestion) => (
{similarQuestion.title} - - {similarQuestion.description} + + {parseHtmlDescriptionWithoutExamples(similarQuestion.description)}
))} diff --git a/frontend/src/components/Questions/QuestionsTable.tsx b/frontend/src/components/Questions/QuestionsTable.tsx index b4bc813f..bbfa3dd9 100644 --- a/frontend/src/components/Questions/QuestionsTable.tsx +++ b/frontend/src/components/Questions/QuestionsTable.tsx @@ -20,7 +20,7 @@ import { Typography, } from "@mui/material"; import { useData } from "../../data/data.context"; -import {parseHtmlDescription} from "../../utils/utils"; +import {parseHtmlDescriptionWithoutExamples} from "../../utils/utils"; interface Question { id: string; @@ -203,7 +203,7 @@ const InterviewQuestionsTable: React.FC = () => { Difficulty: {selectedQuestion.difficulty} - Description: {parseHtmlDescription(selectedQuestion.description)} + Description: {parseHtmlDescriptionWithoutExamples(selectedQuestion.description)} diff --git a/frontend/src/utils/utils.tsx b/frontend/src/utils/utils.tsx index a057a50e..a239a022 100644 --- a/frontend/src/utils/utils.tsx +++ b/frontend/src/utils/utils.tsx @@ -1,12 +1,30 @@ import {decode} from "html-entities"; import htmr from "htmr"; import {ReactNode} from "react"; -import DOMPurify from "dompurify"; export function parseHtmlDescription(description: string): ReactNode { // Decode escaped HTML characters and add text wrap to pre tags in the question description + try { let decodedDescription = decode(description) .replace(/
/g, "
");
-  decodedDescription = DOMPurify.sanitize(decodedDescription);
   return htmr(decodedDescription);
-}
\ No newline at end of file
+  } catch (e) {
+    console.log(e)
+    return description;
+  }
+}
+
+export function parseHtmlDescriptionWithoutExamples(description: string): ReactNode {
+  // Decode escaped HTML characters and add text wrap to pre tags in the question description
+  try {
+  let decodedDescription = decode(description)
+    .replace(/
/g, "
");
+  const exampleIndex = decodedDescription?.indexOf("Example");
+
+  const newDescription = exampleIndex !== -1 ? decodedDescription?.substring(0, exampleIndex) : decodedDescription;
+  return htmr(newDescription);
+  } catch(e) {
+    console.log(e)
+    return description;
+  }
+}