diff --git a/public/problems/medium/mergesort.md b/public/problems/medium/mergesort.md index bf65a19..afa39e9 100644 --- a/public/problems/medium/mergesort.md +++ b/public/problems/medium/mergesort.md @@ -14,8 +14,7 @@ sorting the two halves, and then merging them back together. - If the array has only one element, return the array. (Base case) - Otherwise, divide the array into two halves and recursively sort each half 3. Merge the two halves back together in sorted order. - - Note you'll probablt want to write a helper function to merge the two halves together. - You will need to define this function inside the `mergeSort` function. + - Note you'll probably want to write a helper function to merge the two halves together. - The `merge` function should take two arrays as arguments and return a single sorted array. - How can you use the fact that the two halves are already sorted to merge them together efficiently? 4. Return the sorted array. diff --git a/src/problem/CodeRunner.ts b/src/problem/CodeRunner.ts index a31d0ea..b7762bc 100644 --- a/src/problem/CodeRunner.ts +++ b/src/problem/CodeRunner.ts @@ -540,8 +540,8 @@ ${solutionCode} } else { testResults.returnedResults.push(safeToString(result)); } - - if (result !== expectedResult) { + + if (result.type === expectedResult.type && result.toString() !== expectedResult.toString()) { testResults.testResults.push(TestResult.Failed); } else { testResults.testResults.push(TestResult.Passed); diff --git a/src/problem/Help.tsx b/src/problem/Help.tsx index 17a2aae..e56456c 100644 --- a/src/problem/Help.tsx +++ b/src/problem/Help.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, {ReactElement} from "react"; import {marked, saveUserData, UserData} from "./Problem"; import DOMPurify from "dompurify"; import {expireToken, getToken, isLoggedIn, logIn} from "../auth/AuthHelper"; @@ -10,12 +10,15 @@ import {Token, Tokens} from "marked"; export const LOADING_MESSAGE = "Requesting help from the AI tutor..."; +export const NEXT_HELP_TIME = "NEXT_HELP_TIME" + + export function HelpBoxAndButton(problemData: ProblemData, setUserData: (userData: UserData) => void, runTests: () => UserData, response: string, setResponse: (response: string) => void): - { helpButton: React.JSX.Element, helpBox: React.JSX.Element } { + { helpButton: ReactElement, helpBox: ReactElement } { function handleHelpRequest(event: React.MouseEvent) { event.currentTarget.setAttribute("disabled", "true"); @@ -62,6 +65,7 @@ export function HelpBoxAndButton(problemData: ProblemData, return; } + localStorage.setItem(NEXT_HELP_TIME, (Date.now() + json.wait_time * 1000).toString()); if (json.status === 429) { setResponse("You have made too many requests to the AI tutor. Please try again later."); diff --git a/src/problem/Problem.tsx b/src/problem/Problem.tsx index b959b15..307327c 100644 --- a/src/problem/Problem.tsx +++ b/src/problem/Problem.tsx @@ -3,7 +3,7 @@ import {markedHighlight} from "marked-highlight"; import hljs from "highlight.js/lib/common"; import React, {lazy, Suspense, useEffect, useState} from "react"; import DOMPurify from "dompurify"; -import {HelpBoxAndButton} from "./Help"; +import {HelpBoxAndButton, NEXT_HELP_TIME} from "./Help"; import {useParams} from "react-router-dom"; import 'katex/dist/katex.min.css'; import {getUserName} from "../auth/AuthHelper"; @@ -51,8 +51,9 @@ export default function Problem() { const [userData, setUserData] = useState(null as unknown as UserData); const [helpResponse, setHelpResponse] = useState("When you press \"I'm stuck\", the AI tutor will respond here."); const [magicLinksHover, setMagicLinks] = useState({ - anchorEl: null as (HTMLElement | null), + anchorEl: null as (React.JSX.Element | null), magicLink: "", + highlight: true }) function onCodeSubmit() { @@ -131,17 +132,19 @@ export default function Problem() { let descParsed = DOMPurify.sanitize(marked.parse(problemData.preProblemDescription + "\n\n" + problemData.description) as string); - const handlePopoverOpen = (event: React.MouseEvent, magicLink: string) => { + const handlePopoverOpen = (event: React.MouseEvent, magicLink: string, highlight = true) => { setMagicLinks({ - anchorEl: event.currentTarget as HTMLElement, - magicLink: magicLink + anchorEl: event.currentTarget as unknown as React.JSX.Element, + magicLink: magicLink, + highlight: highlight }); }; const handlePopoverClose = () => { setMagicLinks({ anchorEl: null, - magicLink: magicLinksHover.magicLink + magicLink: magicLinksHover.magicLink, + highlight: magicLinksHover.highlight }); }; @@ -225,8 +228,31 @@ export default function Problem() { } - let highlightHover = hljs.highlight(magicLinksHover.magicLink, {language: hljsLang}); - let hoverHtml = DOMPurify.sanitize(highlightHover.value.replace(/\n/g, "
")); + let highlightHover; + if (magicLinksHover.highlight) { + highlightHover = hljs.highlight(magicLinksHover.magicLink, {language: hljsLang}).value; + } else { + highlightHover = magicLinksHover.magicLink; + } + let hoverHtml = DOMPurify.sanitize(highlightHover.replace(/\n/g, "
")); + + let helpButtonHtml; + if (localStorage.getItem(NEXT_HELP_TIME) !== null) { + helpButtonHtml = { + let timeToNextHelp = parseInt(localStorage.getItem(NEXT_HELP_TIME) as string); + let timeToNextHelpSeconds = Math.ceil((timeToNextHelp - Date.now()) / 1000); + if (timeToNextHelpSeconds > 0) { + handlePopoverOpen(e, "You can request help again in " + timeToNextHelpSeconds + " seconds", false) + } + }} + onMouseLeave={handlePopoverClose}> + {helpButton} + + } else { + helpButtonHtml = {helpButton} + } + return (
@@ -252,7 +278,8 @@ export default function Problem() {

{hiddenTestText}

- {helpButton} + + {helpButtonHtml}
{helpBox}
@@ -263,7 +290,7 @@ export default function Problem() { pointerEvents: 'none', }} open={open} - anchorEl={magicLinksHover.anchorEl} + anchorEl={magicLinksHover.anchorEl as Element | null} anchorOrigin={{ vertical: 'bottom', horizontal: 'left',