Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
8 changes: 4 additions & 4 deletions app/components/developmentToolsComponent/apiKeyGenerator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import React, { useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";

type Charset = {
upper: boolean;
Expand Down Expand Up @@ -71,19 +71,19 @@ const ApiKeyGenerator: React.FC = () => {
const [autoUpdate, setAutoUpdate] = useState(false);
const fileRef = useRef<HTMLInputElement>(null);

const run = () => {
const run = useCallback(() => {
const clampedLen = Math.max(4, Math.min(256, Number(length) || 32));
const clampedCount = Math.max(1, Math.min(100, Number(count) || 1));
const gSize = groupSize && groupSize > 0 ? Math.max(1, Math.min(32, Number(groupSize) || 0)) : null;
const out: string[] = [];
for (let i = 0; i < clampedCount; i++) out.push(generateKey(clampedLen, charset, { groupSize: gSize, prefix, suffix }));
setKeys(out);
};
}, [length, count, groupSize, charset, prefix, suffix]);

useEffect(() => {
if (!autoUpdate) return;
run();
}, [length, count, groupSize, charset, prefix, suffix, autoUpdate]);
}, [run, autoUpdate]);

const onCopy = async () => {
try {
Expand Down
12 changes: 6 additions & 6 deletions app/components/developmentToolsComponent/fibonacciCalculator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import React, { useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";

type Mode = "nth" | "sequence";

Expand Down Expand Up @@ -50,14 +50,14 @@ const FibonacciCalculator: React.FC = () => {
}
};

const computeNth = (n: number): string => {
const computeNth = useCallback((n: number): string => {
// Interpret n according to zeroIndexed toggle: if one-indexed, compute F(n) where input 1 -> F(1)=1
const effective = zeroIndexed ? BigInt(n) : BigInt(Math.max(n, 1) - 1);
const [fn] = fibFastDoubling(effective);
return formatBigInt(fn, thousandsSep);
};
}, [zeroIndexed, thousandsSep]);

const computeSequence = (count: number): string => {
const computeSequence = useCallback((count: number): string => {
// Build sequence up to count terms. If includeZero is true, start from F(0)=0, else start from F(1)=1.
if (count === 0) return "";
const result: string[] = [];
Expand All @@ -71,7 +71,7 @@ const FibonacciCalculator: React.FC = () => {
}
const sep = separator === "comma" ? ", " : separator === "space" ? " " : "\n";
return result.join(sep);
};
}, [includeZero, thousandsSep, separator]);

useEffect(() => {
if (!autoConvert) return;
Expand All @@ -85,7 +85,7 @@ const FibonacciCalculator: React.FC = () => {
} else {
setOutput(computeSequence(n));
}
}, [input, autoConvert, mode, includeZero, thousandsSep, separator, zeroIndexed]);
}, [input, autoConvert, mode, computeNth, computeSequence]);

const onConvert = () => {
const n = parseNonNegativeInt(input);
Expand Down
174 changes: 174 additions & 0 deletions app/components/developmentToolsComponent/sudokuSolver.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
"use client";

import React, { useState } from "react";

const SudokuSolver: React.FC = () => {
const [grid, setGrid] = useState<(number | null)[][]>(Array(9).fill(null).map(() => Array(9).fill(null)));
const [status, setStatus] = useState<string>("");
const [difficulty, setDifficulty] = useState<"Easy" | "Medium" | "Hard">("Medium");

// Helper to check if safe
const isSafe = (board: (number | null)[][], row: number, col: number, num: number) => {
// Check row
for (let x = 0; x < 9; x++) if (board[row][x] === num) return false;
// Check col
for (let x = 0; x < 9; x++) if (board[x][col] === num) return false;
// Check box
const startRow = row - (row % 3);
const startCol = col - (col % 3);
for (let i = 0; i < 3; i++)
for (let j = 0; j < 3; j++)
if (board[i + startRow][j + startCol] === num) return false;
return true;
};

const solve = (board: (number | null)[][]): boolean => {
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 9; col++) {
if (board[row][col] === null) {
for (let num = 1; num <= 9; num++) {
if (isSafe(board, row, col, num)) {
board[row][col] = num;
if (solve(board)) return true;
board[row][col] = null;
}
}
return false;
}
}
}
return true;
};

const handleSolve = () => {
const board = grid.map(row => [...row]);
if (solve(board)) {
setGrid(board);
setStatus("Solved!");
} else {
setStatus("No solution found.");
}
};

const handleClear = () => {
setGrid(Array(9).fill(null).map(() => Array(9).fill(null)));
setStatus("");
};

const isSafeBox = (board: (number | null)[][], rowStart: number, colStart: number, num: number) => {
for (let i = 0; i < 3; i++)
for (let j = 0; j < 3; j++)
if (board[rowStart + i][colStart + j] === num) return false;
return true;
};

const fillBox = (board: (number | null)[][], row: number, col: number) => {
let num: number;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
do {
num = Math.floor(Math.random() * 9) + 1;
} while (!isSafeBox(board, row, col, num));
board[row + i][col + j] = num;
}
}
};

const generate = () => {
// Start fresh
const board = Array(9).fill(null).map(() => Array(9).fill(null));

// Fill diagonal 3x3 matrices (independent)
for (let i = 0; i < 9; i = i + 3) {
fillBox(board, i, i);
}

// Solve remaining
if (!solve(board)) {
setStatus("Failed to generate. Try again.");
return;
}

// Remove digits based on difficulty
// Easy: ~30 removed (keep 51), Medium: ~45 removed (keep 36), Hard: ~55 removed (keep 26)
// Actually, usually it's specified by givens.
// Easy: 40-50 givens. Medium: 30-40 givens. Hard: 20-30 givens.
// Let's remove cells.
let attempts = difficulty === "Easy" ? 40 : difficulty === "Medium" ? 50 : 60;

while (attempts > 0) {
let row = Math.floor(Math.random() * 9);
let col = Math.floor(Math.random() * 9);
while (board[row][col] === null) {
row = Math.floor(Math.random() * 9);
col = Math.floor(Math.random() * 9);
}
board[row][col] = null;
attempts--;
}
setGrid(board);
setStatus("");
};

const handleChange = (row: number, col: number, value: string) => {
const val = parseInt(value);
const newGrid = grid.map(r => [...r]);
if (value === "" || isNaN(val)) {
newGrid[row][col] = null;
} else if (val >= 1 && val <= 9) {
newGrid[row][col] = val;
}
setGrid(newGrid);
};

return (
<div className="md:mt-8 mt-4 text-white">
<div className="flex-1 flex items-center justify-center">
<div className="w-full bg-[#FFFFFF1A] rounded-2xl shadow-lg p-8">
<div className="md:w-[950px] mx-auto space-y-6">
<h2 className="text-2xl font-bold text-center">Sudoku Solver & Generator</h2>

<div className="flex justify-center gap-4 flex-wrap">
<select
value={difficulty}
onChange={(e) => setDifficulty(e.target.value as any)}
className="bg-black/20 border border-white/20 rounded px-3 py-2"
>
<option value="Easy">Easy</option>
<option value="Medium">Medium</option>
<option value="Hard">Hard Level</option>
</select>
<button onClick={generate} className="px-4 py-2 bg-blue-600 rounded hover:bg-blue-700 font-bold">Generate</button>
<button onClick={handleSolve} className="px-4 py-2 bg-green-600 rounded hover:bg-green-700 font-bold">Solve</button>
<button onClick={handleClear} className="px-4 py-2 bg-red-600 rounded hover:bg-red-700 font-bold">Clear</button>
</div>

<div className="flex justify-center overflow-auto p-2">
<div className="grid grid-cols-9 gap-0 border-4 border-white bg-white text-black w-fit">
{grid.map((row, rowIndex) => (
row.map((cell, colIndex) => (
<input
key={`${rowIndex}-${colIndex}`}
type="text"
maxLength={1}
value={cell ?? ""}
onChange={(e) => handleChange(rowIndex, colIndex, e.target.value)}
className={`w-10 h-10 text-center font-bold text-lg focus:outline-none focus:bg-blue-100
${colIndex % 3 === 2 && colIndex !== 8 ? "border-r-2 border-r-gray-800" : "border-r border-gray-300"}
${rowIndex % 3 === 2 && rowIndex !== 8 ? "border-b-2 border-b-gray-800" : "border-b border-gray-300"}
`}
/>
))
))}
</div>
</div>

{status && <div className="text-center text-xl font-bold mt-4">{status}</div>}
</div>
</div>
</div>
</div>
);
};

export default SudokuSolver;
13 changes: 13 additions & 0 deletions app/libs/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import RoundingCalculator from '../components/developmentToolsComponent/rounding
import SentenceCounterComponent from '../components/developmentToolsComponent/sentenceCounterComponent';
import SortNumbers from '../components/developmentToolsComponent/sortNumbers';
import SortWords from '../components/developmentToolsComponent/sortWords';
import SudokuSolver from '../components/developmentToolsComponent/sudokuSolver';
import TextToOneLine from '../components/developmentToolsComponent/textToOneLine';
import TxtToCsvConverter from '../components/developmentToolsComponent/txtToCsvConverter';
import UpperCaseConverterComponent from '../components/developmentToolsComponent/upperCaseConverterComponent';
Expand Down Expand Up @@ -1589,6 +1590,13 @@ export const developmentToolsCategoryContent: any = {
description: 'Convert HTML to Jade.',
},
],
Category176: [
{
url: '/sudoku-solver',
title: 'Sudoku Solver & Generator',
description: 'Solve Sudoku puzzles instantly or generate new ones with difficulty levels.',
},
],
};

export const PATHS = {
Expand Down Expand Up @@ -1767,6 +1775,7 @@ export const PATHS = {
CSS_TO_LESS: '/css-to-less',
CRONTAB_GENERATOR: '/crontab-generator',
MORSE_CODE_TRANSLATOR: '/morse-code-translator',
SUDOKU_SOLVER: '/sudoku-solver',
};

export const developmentToolsRoutes = [
Expand Down Expand Up @@ -2466,6 +2475,10 @@ export const developmentToolsRoutes = [
path: PATHS.HTML_TO_JADE,
component: <HtmlToJade />,
},
{
path: PATHS.SUDOKU_SOLVER,
component: <SudokuSolver />,
},
];

// lorem ipsum text
Expand Down
75 changes: 75 additions & 0 deletions app/libs/developmentToolsConstant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17169,4 +17169,79 @@ family[1]: "Beth"`,
og_image: '/images/og-images/Cover.png',
},
},
[`sudoku-solver`]: {
hero_section: {
title: 'Sudoku Solver & Generator',
description:
'A free online tool to solve Sudoku puzzles instantly and generate new puzzles with different difficulty levels.',
},
development_tools_list: [
{ tool: 'Random Number Generator', url: PATHS.RANDOM_NUMBER_GENERATOR },
{ tool: 'Sorting List', url: PATHS.SORTING_LIST },
],
development_tools_about_details: {
about_title: 'What is the Sudoku Solver?',
about_description: [
{
description:
'The Sudoku Solver is a powerful tool that allows you to solve any 9x9 Sudoku puzzle instantly. It uses an advanced backtracking algorithm to find the solution.',
},
{
description:
'Additionally, it features a Sudoku Generator that can create new puzzles with varying difficulty levels: Easy, Medium, and Hard (Hard Level).',
},
],
},
development_tools_steps_guide: {
guide_title: 'How to use',
guide_description: 'Using the tool is simple:',
steps: [
{
step_key: 'Step 1:',
step_title: 'Generate or Input:',
step_description:
'Click "Generate" to create a new puzzle, or manually enter numbers into the grid.',
},
{
step_key: 'Step 2:',
step_title: 'Select Difficulty:',
step_description:
'If generating, select the difficulty level (Easy, Medium, Hard Level) from the dropdown.',
},
{
step_key: 'Step 3:',
step_title: 'Solve:',
step_description:
'Click "Solve" to see the solution instantly.',
},
],
},
development_tools_how_use: {
how_use_title: 'Use Cases',
how_use_description: 'Great for:',
point: [
{
title: 'Entertainment',
description: 'Play and solve Sudoku puzzles for fun.',
},
{
title: 'Learning',
description: 'Understand Sudoku strategies and logic.',
},
{
title: 'Testing',
description: 'Test Sudoku solving algorithms and logic.',
},
],
},
meta_data: {
meta_title: 'Sudoku Solver & Generator - Online Tool',
meta_description:
'Solve Sudoku puzzles instantly and generate new ones with difficulty levels. Free online tool.',
og_title: 'Sudoku Solver & Generator - Developer Utility',
og_description:
'Solve and generate Sudoku puzzles. Features Easy, Medium, and Hard levels.',
og_image: '/images/og-images/Cover.png',
},
},
};
4 changes: 4 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.