diff --git a/JustBigO(Fun).Tests/Controllers/HomeControllerTests.cs b/JustBigO(Fun).Tests/Controllers/HomeControllerTests.cs
index 0a42306..c73d868 100644
--- a/JustBigO(Fun).Tests/Controllers/HomeControllerTests.cs
+++ b/JustBigO(Fun).Tests/Controllers/HomeControllerTests.cs
@@ -25,7 +25,7 @@ public HomeControllerTests()
}
[Fact]
- public async Task Index_ReturnsViewWithProblems()
+ public async Task Problems_ReturnsViewWithProblems()
{
// Arrange
using var db = new ApplicationDbContext(_options);
@@ -44,7 +44,7 @@ public async Task Index_ReturnsViewWithProblems()
};
// Act
- var result = await controller.Index(null, null);
+ var result = await controller.Problems(null, null);
// Assert
var viewResult = Assert.IsType(result);
@@ -53,7 +53,7 @@ public async Task Index_ReturnsViewWithProblems()
}
[Fact]
- public async Task Index_FiltersByDifficulty()
+ public async Task Problems_FiltersByDifficulty()
{
// Arrange
using var db = new ApplicationDbContext(_options);
@@ -72,7 +72,7 @@ public async Task Index_FiltersByDifficulty()
};
// Act
- var result = await controller.Index(null, "Easy");
+ var result = await controller.Problems(null, "Easy");
// Assert
var viewResult = Assert.IsType(result);
diff --git a/JustBigO(Fun).Tests/Services/GeminiHintGeneratorTests.cs b/JustBigO(Fun).Tests/Services/GeminiHintGeneratorTests.cs
index 6ed43e9..735aea5 100644
--- a/JustBigO(Fun).Tests/Services/GeminiHintGeneratorTests.cs
+++ b/JustBigO(Fun).Tests/Services/GeminiHintGeneratorTests.cs
@@ -1,6 +1,9 @@
using Microsoft.Extensions.Configuration;
using Moq;
+using Moq.Protected;
+using System.Net;
using System.Net.Http;
+using System.Threading;
using System.Threading.Tasks;
using Xunit;
using JustBigO_Fun_.Services;
@@ -25,5 +28,54 @@ public async Task GenerateHintAsync_ReturnsMissingKeyMessage_WhenApiKeyIsMissing
// Assert
Assert.Contains("GeminiApiKey is missing", result);
}
+
+ [Fact]
+ public async Task GenerateHintAsync_StripsCodeAndLimitsToTwoSentences()
+ {
+ // Arrange
+ var apiResponse = """
+ {
+ "candidates": [
+ {
+ "content": {
+ "parts": [
+ {
+ "text": "Try tracking the needed counts with a hash map. ```python\nfor x in nums:\n pass\n``` Then move two pointers only when the window is valid. Extra explanation that should be removed."
+ }
+ ]
+ }
+ }
+ ]
+ }
+ """;
+
+ var mockHandler = new Mock(MockBehavior.Strict);
+ mockHandler
+ .Protected()
+ .Setup>(
+ "SendAsync",
+ ItExpr.IsAny(),
+ ItExpr.IsAny())
+ .ReturnsAsync(new HttpResponseMessage
+ {
+ StatusCode = HttpStatusCode.OK,
+ Content = new StringContent(apiResponse)
+ });
+
+ var httpClient = new HttpClient(mockHandler.Object);
+ var mockConfig = new Mock();
+ mockConfig.Setup(c => c["GeminiApiKey"]).Returns("fake-key");
+ var service = new GeminiHintGenerator(httpClient, mockConfig.Object);
+
+ // Act
+ var result = await service.GenerateHintAsync("Two Sum", "desc", "code", "python");
+
+ // Assert
+ Assert.DoesNotContain("```", result);
+ Assert.DoesNotContain("pass", result);
+ Assert.DoesNotContain("Extra explanation", result);
+ Assert.Equal("Try tracking the needed counts with a hash map. Then move two pointers only when the window is valid.", result);
+ }
}
}
+
diff --git a/JustBigO(Fun)/Controllers/HomeController.cs b/JustBigO(Fun)/Controllers/HomeController.cs
index 2fa0712..3d92f70 100644
--- a/JustBigO(Fun)/Controllers/HomeController.cs
+++ b/JustBigO(Fun)/Controllers/HomeController.cs
@@ -24,9 +24,18 @@ public HomeController(ILogger logger, ApplicationDbContext db, I
_markdown = markdown;
}
- // --- INCEPUT MODIFICARE ---
- // Am adăugat parametrul `difficultyFilter` și am implementat logica de filtrare `.Where(...)`
- public async Task Index(string sortOrder, string difficultyFilter)
+ public IActionResult Index()
+ {
+ return View();
+ }
+
+ public async Task Problems(string sortOrder, string difficultyFilter)
+ {
+ var problemItems = await BuildProblemListAsync(sortOrder, difficultyFilter);
+ return View(problemItems);
+ }
+
+ private async Task> BuildProblemListAsync(string sortOrder, string difficultyFilter)
{
// Salvăm parametrii în ViewData pentru a menține starea în butoanele de pe UI
ViewData["DifficultySortParm"] = sortOrder == "diff_asc" ? "diff_desc" : "diff_asc";
@@ -76,7 +85,7 @@ public async Task Index(string sortOrder, string difficultyFilter
_ => problemItems.OrderBy(p => problems.First(x => x.Id == p.Id).OrderIndex)
};
- return View(problemItems.ToList());
+ return problemItems.ToList();
}
private static int GetDifficultyWeight(string difficulty)
@@ -89,8 +98,6 @@ private static int GetDifficultyWeight(string difficulty)
_ => 0
};
}
- // --- SFARSIT MODIFICARE ---
-
public async Task Solve(int? id)
{
Problem? problem;
diff --git a/JustBigO(Fun)/JustBigO(Fun).csproj b/JustBigO(Fun)/JustBigO(Fun).csproj
index fbfdd4c..906bd03 100644
--- a/JustBigO(Fun)/JustBigO(Fun).csproj
+++ b/JustBigO(Fun)/JustBigO(Fun).csproj
@@ -25,6 +25,7 @@
+
diff --git a/JustBigO(Fun)/Services/GeminiHintGenerator.cs b/JustBigO(Fun)/Services/GeminiHintGenerator.cs
index c99db76..f07df4c 100644
--- a/JustBigO(Fun)/Services/GeminiHintGenerator.cs
+++ b/JustBigO(Fun)/Services/GeminiHintGenerator.cs
@@ -1,6 +1,7 @@
using Microsoft.Extensions.Configuration;
using System.Text;
using System.Text.Json;
+using System.Text.RegularExpressions;
namespace JustBigO_Fun_.Services;
@@ -28,9 +29,13 @@ public async Task GenerateHintAsync(string problemTitle, string problemD
var prompt = $"""
You are a programming mentor for an algorithms platform.
- Return exactly one concise hint in English, max 2 short paragraphs.
- Do NOT provide full solution code.
- Keep the hint actionable and contextual.
+ Return exactly ONE subtle hint in English, maximum 1-2 short sentences.
+ STRICT RULES:
+ - Do NOT provide code, pseudocode, or step-by-step algorithm.
+ - Do NOT reveal the full strategy or optimal full solution.
+ - Prefer a nudge: mention one data structure, one invariant, or one leading question.
+ - If the user is already close, only point to the next tiny step.
+ - Keep it spoiler-free and concise.
Note: The platform uses a Standard IO model (Competitive Programming style). The user must READ from stdin and PRINT to stdout.
Problem title: {problemTitle}
@@ -86,11 +91,46 @@ Problem statement (HTML possible):
return "No valid hint was returned. Please try again.";
}
- return hintText.Trim();
+ return SanitizeHint(hintText);
}
catch
{
return "An error occurred while generating the hint. Please try again.";
}
}
+
+ private static string SanitizeHint(string hintText)
+ {
+ if (string.IsNullOrWhiteSpace(hintText))
+ return "Try focusing on one small invariant that must stay true at each step.";
+
+ // Remove fenced code blocks or inline code to avoid accidental full solutions.
+ var sanitized = Regex.Replace(hintText, "```[\\s\\S]*?```", string.Empty);
+ sanitized = Regex.Replace(sanitized, "`[^`]*`", string.Empty).Trim();
+
+ // Keep only first 1-2 sentences to force a subtle nudge.
+ var sentenceMatches = Regex.Matches(sanitized, @"[^.!?]+[.!?]?");
+ if (sentenceMatches.Count > 0)
+ {
+ var sentenceCount = Math.Min(2, sentenceMatches.Count);
+ var parts = new List(sentenceCount);
+ for (var i = 0; i < sentenceCount; i++)
+ {
+ var s = sentenceMatches[i].Value.Trim();
+ if (!string.IsNullOrWhiteSpace(s))
+ parts.Add(s);
+ }
+
+ sanitized = string.Join(" ", parts).Trim();
+ }
+
+ if (string.IsNullOrWhiteSpace(sanitized))
+ return "Try focusing on one small invariant that must stay true at each step.";
+
+ // Gentle length cap to reduce chance of spoiler-ish detail.
+ if (sanitized.Length > 260)
+ sanitized = sanitized[..260].TrimEnd() + "...";
+
+ return sanitized;
+ }
}
diff --git a/JustBigO(Fun)/Services/HtmlSanitizerService.cs b/JustBigO(Fun)/Services/HtmlSanitizerService.cs
index fdfbfb6..21924e2 100644
--- a/JustBigO(Fun)/Services/HtmlSanitizerService.cs
+++ b/JustBigO(Fun)/Services/HtmlSanitizerService.cs
@@ -1,3 +1,8 @@
+// To fix CS0246, you must add a reference to the Ganss.Xss NuGet package.
+// In Visual Studio, right-click your project > Manage NuGet Packages > Browse > search for "Ganss.Xss" > Install.
+// Or, run the following command in the Package Manager Console:
+// Install-Package Ganss.Xss
+
using Ganss.Xss;
namespace JustBigO_Fun_.Services;
diff --git a/JustBigO(Fun)/Views/Home/Index.cshtml b/JustBigO(Fun)/Views/Home/Index.cshtml
index 246398f..2d2c963 100644
--- a/JustBigO(Fun)/Views/Home/Index.cshtml
+++ b/JustBigO(Fun)/Views/Home/Index.cshtml
@@ -1,7 +1,5 @@
-@model IEnumerable
@{
- ViewData["Title"] = "Dashboard";
- string GetDifficultyClass(string d) => d?.ToLowerInvariant() switch { "medium" => "medium", "hard" => "hard", _ => "easy" };
+ ViewData["Title"] = "Home";
}
@@ -25,7 +23,7 @@
and get instant feedback from smart agents on complexity, transpilations, and hints.
-
+
-
-
-
-
-
- | Problem |
- Tags |
-
-
- Difficulty ↕
-
- |
- Best status |
-
-
-
- @foreach (var p in Model ?? Enumerable.Empty())
- {
-
-
- | @p.Title |
- @p.Tags |
- @p.Difficulty |
-
-
- @{
- string statusClass = "";
- if (p.BestStatus == "Accepted") statusClass = "jbo-status-chip--accepted";
- else if (p.BestStatus == "TimeLimitExceeded") statusClass = "jbo-status-chip--tle";
- else if (p.BestStatus != "—") statusClass = "jbo-status-chip--wa";
- }
- @p.BestStatus
- |
-
- }
-
-
-
-
-