equationgen / index.html
ffonavia's picture
Add 2 files
76af358 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Linear Equation Generator with Integer Solutions</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.equation {
font-family: 'Times New Roman', Times, serif;
font-size: 1.5rem;
}
.hint {
transition: all 0.3s ease;
max-height: 0;
overflow: hidden;
opacity: 0;
}
.hint.active {
max-height: 200px;
padding: 0.5rem 0;
opacity: 1;
}
.fade-in {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-12 max-w-3xl">
<div class="bg-white rounded-xl shadow-lg overflow-hidden">
<div class="p-8">
<h1 class="text-3xl font-bold text-center text-indigo-700 mb-2">
<i class="fas fa-square-root-alt mr-2"></i>Linear Equation Generator
</h1>
<p class="text-gray-600 text-center mb-8">Practice solving linear equations with integer solutions</p>
<div class="flex flex-col md:flex-row gap-6 mb-8">
<div class="flex-1 bg-indigo-50 p-6 rounded-lg">
<h2 class="text-xl font-semibold text-indigo-800 mb-4">
<i class="fas fa-sliders-h mr-2"></i>Settings
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Difficulty</label>
<select id="difficulty" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<option value="easy">Easy (one-step)</option>
<option value="medium">Medium (two-step)</option>
<option value="hard">Hard (multi-step)</option>
<option value="parentheses" selected>With Parentheses</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Variable</label>
<input type="text" id="variable" value="x" maxlength="1" class="w-16 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 text-center">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Number Range</label>
<div class="flex items-center gap-2">
<input type="number" id="minNum" value="-10" class="w-20 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
<span>to</span>
<input type="number" id="maxNum" value="10" class="w-20 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500">
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Solution Type</label>
<div class="flex space-x-4">
<label class="inline-flex items-center">
<input type="radio" name="solutionType" value="any" checked class="h-4 w-4 text-indigo-600 focus:ring-indigo-500">
<span class="ml-2 text-gray-700">Any integers</span>
</label>
<label class="inline-flex items-center">
<input type="radio" name="solutionType" value="positive" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500">
<span class="ml-2 text-gray-700">Only positive</span>
</label>
</div>
</div>
</div>
<button id="generateBtn" class="mt-6 w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-md transition duration-150 ease-in-out transform hover:scale-105">
<i class="fas fa-random mr-2"></i>Generate Equation
</button>
</div>
<div class="flex-1 bg-white p-6 rounded-lg border border-gray-200">
<h2 class="text-xl font-semibold text-gray-800 mb-4">
<i class="fas fa-question-circle mr-2"></i>Problem
</h2>
<div id="equationContainer" class="equation bg-gray-50 p-4 rounded-lg mb-4 text-center min-h-16 flex items-center justify-center">
<p class="text-gray-500">Click "Generate Equation" to start</p>
</div>
<div class="mt-6">
<div class="flex items-center justify-between mb-1">
<label for="userAnswer" class="block text-sm font-medium text-gray-700">Your Answer</label>
<div class="relative">
<i class="fas fa-lightbulb text-yellow-500 cursor-pointer hint-icon"></i>
<div class="hint absolute right-0 top-full mt-1 w-64 bg-yellow-50 text-yellow-800 text-sm p-2 rounded-md shadow-lg z-10">
Enter the numerical value only (e.g. 5 or -3)
</div>
</div>
</div>
<input type="text" id="userAnswer" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500" placeholder="Enter the value of x">
</div>
<button id="checkBtn" class="mt-4 w-full bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-md transition duration-150 ease-in-out">
<i class="fas fa-check mr-2"></i>Check Answer
</button>
<div id="feedback" class="mt-4 p-3 rounded-md hidden"></div>
<button id="showStepsBtn" class="mt-2 w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-md transition duration-150 ease-in-out hidden">
<i class="fas fa-list-ol mr-2"></i>Show Solution Steps
</button>
<div id="solutionSteps" class="mt-4 hidden bg-blue-50 p-4 rounded-md text-sm space-y-2"></div>
</div>
</div>
<div class="bg-gray-50 p-6 rounded-lg">
<h2 class="text-xl font-semibold text-gray-800 mb-4">
<i class="fas fa-history mr-2"></i>Recent Problems
</h2>
<div id="history" class="space-y-2">
<!-- History items will be added here -->
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM elements
const generateBtn = document.getElementById('generateBtn');
const checkBtn = document.getElementById('checkBtn');
const equationContainer = document.getElementById('equationContainer');
const userAnswer = document.getElementById('userAnswer');
const feedback = document.getElementById('feedback');
const history = document.getElementById('history');
const difficulty = document.getElementById('difficulty');
const variable = document.getElementById('variable');
const minNum = document.getElementById('minNum');
const maxNum = document.getElementById('maxNum');
const showStepsBtn = document.getElementById('showStepsBtn');
const solutionSteps = document.getElementById('solutionSteps');
const solutionTypeRadios = document.getElementsByName('solutionType');
// Current equation data
let currentEquation = null;
let currentSolution = null;
let currentSteps = [];
// Generate a random integer between min and max
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Generate a non-zero random integer between min and max
function randomNonZero(min, max) {
let num = 0;
while (num === 0) {
num = randomInt(min, max);
}
return num;
}
// Get selected solution type
function getSolutionType() {
return document.querySelector('input[name="solutionType"]:checked').value;
}
// Generate a linear equation with integer solution
function generateEquation() {
const varSymbol = variable.value || 'x';
const min = parseInt(minNum.value) || -10;
const max = parseInt(maxNum.value) || 10;
const diff = difficulty.value;
const solutionType = getSolutionType();
// First generate a random integer solution
let solution;
if (solutionType === 'positive') {
// For positive solutions, we need to adjust the range
const positiveMin = Math.max(1, min);
const positiveMax = Math.max(1, max);
solution = randomInt(positiveMin, positiveMax);
} else {
// For any integer solutions
solution = randomInt(min, max);
}
let equation = '';
let steps = [];
if (diff === 'easy') {
// ax = b format where b is divisible by a
const a = randomNonZero(min, max);
const b = a * solution;
equation = `${a}${varSymbol} = ${b}`;
steps = [
`Given equation: ${equation}`,
`Divide both sides by ${a}: ${varSymbol} = ${b}/${a}`,
`Solution: ${varSymbol} = ${solution}`
];
}
else if (diff === 'medium') {
// ax + b = c format where (c - b) is divisible by a
const a = randomNonZero(min, max);
const b = randomInt(min, max);
const c = a * solution + b;
equation = `${a}${varSymbol} ${b < 0 ? '-' : '+'} ${Math.abs(b)} = ${c}`;
steps = [
`Given equation: ${equation}`,
`Subtract ${b} from both sides: ${a}${varSymbol} = ${c - b}`,
`Divide both sides by ${a}: ${varSymbol} = ${solution}`,
`Solution: ${varSymbol} = ${solution}`
];
}
else if (diff === 'hard') {
// ax + b = cx + d format where (d - b) is divisible by (a - c)
const a = randomNonZero(min, max);
const c = randomNonZero(min, max);
// Ensure a ≠ c
while (a === c) {
c = randomNonZero(min, max);
}
const b = randomInt(min, max);
const d = (a - c) * solution + b;
equation = `${a}${varSymbol} ${b < 0 ? '-' : '+'} ${Math.abs(b)} = ${c}${varSymbol} ${d < 0 ? '-' : '+'} ${Math.abs(d)}`;
steps = [
`Given equation: ${equation}`,
`Subtract ${c}${varSymbol} from both sides: ${(a - c)}${varSymbol} ${b < 0 ? '-' : '+'} ${Math.abs(b)} = ${d}`,
`Subtract ${b} from both sides: ${(a - c)}${varSymbol} = ${d - b}`,
`Divide both sides by ${a - c}: ${varSymbol} = ${solution}`,
`Solution: ${varSymbol} = ${solution}`
];
}
else if (diff === 'parentheses') {
// Randomly choose between different formats with parentheses
const format = randomInt(1, 3);
if (format === 1) {
// a(bx + c) = d where d is divisible by a and (d/a - c) is divisible by b
const a = randomNonZero(min, max);
const b = randomNonZero(min, max);
const c = randomInt(min, max);
const d = a * (b * solution + c);
equation = `${a}(${b}${varSymbol} ${c < 0 ? '-' : '+'} ${Math.abs(c)}) = ${d}`;
steps = [
`Given equation: ${equation}`,
`Divide both sides by ${a}: ${b}${varSymbol} ${c < 0 ? '-' : '+'} ${Math.abs(c)} = ${b * solution + c}`,
`${c < 0 ? 'Add' : 'Subtract'} ${Math.abs(c)} to both sides: ${b}${varSymbol} = ${b * solution}`,
`Divide both sides by ${b}: ${varSymbol} = ${solution}`,
`Solution: ${varSymbol} = ${solution}`
];
}
else if (format === 2) {
// a(bx + c) + d = e where (e - d) is divisible by a and ((e - d)/a - c) is divisible by b
const a = randomNonZero(min, max);
const b = randomNonZero(min, max);
const c = randomInt(min, max);
const d = randomInt(min, max);
const e = a * (b * solution + c) + d;
equation = `${a}(${b}${varSymbol} ${c < 0 ? '-' : '+'} ${Math.abs(c)}) ${d < 0 ? '-' : '+'} ${Math.abs(d)} = ${e}`;
steps = [
`Given equation: ${equation}`,
`${d < 0 ? 'Add' : 'Subtract'} ${Math.abs(d)} to both sides: ${a}(${b}${varSymbol} ${c < 0 ? '-' : '+'} ${Math.abs(c)}) = ${a * (b * solution + c)}`,
`Divide both sides by ${a}: ${b}${varSymbol} ${c < 0 ? '-' : '+'} ${Math.abs(c)} = ${b * solution + c}`,
`${c < 0 ? 'Add' : 'Subtract'} ${Math.abs(c)} to both sides: ${b}${varSymbol} = ${b * solution}`,
`Divide both sides by ${b}: ${varSymbol} = ${solution}`,
`Solution: ${varSymbol} = ${solution}`
];
}
else {
// a(bx + c) = d(ex + f) where (a*c - d*f) is divisible by (d*e - a*b)
const a = randomNonZero(min, max);
const b = randomNonZero(min, max);
const c = randomInt(min, max);
const d = randomNonZero(min, max);
const e = randomNonZero(min, max);
const f = randomInt(min, max);
// Calculate to ensure solution is integer
const numerator = a * c - d * f;
const denominator = d * e - a * b;
// Ensure denominator is not zero and divides numerator
while (denominator === 0 || numerator % denominator !== 0) {
b = randomNonZero(min, max);
e = randomNonZero(min, max);
denominator = d * e - a * b;
}
equation = `${a}(${b}${varSymbol} ${c < 0 ? '-' : '+'} ${Math.abs(c)}) = ${d}(${e}${varSymbol} ${f < 0 ? '-' : '+'} ${Math.abs(f)})`;
steps = [
`Given equation: ${equation}`,
`Expand left side: ${a*b}${varSymbol} ${a*c < 0 ? '-' : '+'} ${Math.abs(a*c)} = ${d*e}${varSymbol} ${d*f < 0 ? '-' : '+'} ${Math.abs(d*f)}`,
`Bring all terms to one side: ${(a*b - d*e)}${varSymbol} = ${d*f - a*c}`,
`Divide both sides by ${a*b - d*e}: ${varSymbol} = ${solution}`,
`Solution: ${varSymbol} = ${solution}`
];
}
}
return { equation, solution, steps };
}
// Generate a new equation
generateBtn.addEventListener('click', function() {
const result = generateEquation();
currentEquation = result.equation;
currentSolution = result.solution;
currentSteps = result.steps;
equationContainer.innerHTML = `<span class="equation">${currentEquation}</span>`;
userAnswer.value = '';
feedback.classList.add('hidden');
solutionSteps.classList.add('hidden');
showStepsBtn.classList.add('hidden');
// Focus on answer input
setTimeout(() => userAnswer.focus(), 100);
});
// Check the user's answer
checkBtn.addEventListener('click', function() {
if (!currentEquation) {
feedback.textContent = 'Please generate an equation first!';
feedback.className = 'mt-4 p-3 rounded-md bg-red-100 text-red-800';
feedback.classList.remove('hidden');
return;
}
const userValue = parseFloat(userAnswer.value);
if (isNaN(userValue)) {
feedback.textContent = 'Please enter a valid number!';
feedback.className = 'mt-4 p-3 rounded-md bg-red-100 text-red-800';
feedback.classList.remove('hidden');
return;
}
// Compare with exact integer value
if (userValue === currentSolution) {
feedback.textContent = 'Correct! Well done!';
feedback.className = 'mt-4 p-3 rounded-md bg-green-100 text-green-800';
// Show steps button
showStepsBtn.classList.remove('hidden');
// Add to history
const historyItem = document.createElement('div');
historyItem.className = 'bg-white p-3 rounded-md border border-gray-200 flex justify-between items-center fade-in';
historyItem.innerHTML = `
<div>
<span class="equation">${currentEquation}</span>
<span class="text-gray-500 mx-2">→</span>
<span>${variable.value || 'x'} = ${currentSolution}</span>
</div>
<span class="text-green-500"><i class="fas fa-check-circle"></i></span>
`;
history.prepend(historyItem);
// Limit history to 5 items
if (history.children.length > 5) {
history.removeChild(history.lastChild);
}
} else {
feedback.textContent = `Not quite right. Try again! (Hint: the solution is an integer)`;
feedback.className = 'mt-4 p-3 rounded-md bg-red-100 text-red-800';
showStepsBtn.classList.remove('hidden');
}
feedback.classList.remove('hidden');
});
// Show solution steps
showStepsBtn.addEventListener('click', function() {
if (solutionSteps.classList.contains('hidden')) {
solutionSteps.innerHTML = currentSteps.map(step =>
`<div class="p-2 bg-white rounded border-b border-gray-100">${step}</div>`
).join('');
solutionSteps.classList.remove('hidden');
this.innerHTML = `<i class="fas fa-eye-slash mr-2"></i>Hide Solution Steps`;
} else {
solutionSteps.classList.add('hidden');
this.innerHTML = `<i class="fas fa-list-ol mr-2"></i>Show Solution Steps`;
}
});
// Allow pressing Enter to check answer
userAnswer.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
checkBtn.click();
}
});
// Show hint when hovering over icon
const hintIcon = document.querySelector('.hint-icon');
const hint = document.querySelector('.hint');
hintIcon.addEventListener('mouseenter', function() {
hint.classList.add('active');
});
hintIcon.addEventListener('mouseleave', function() {
hint.classList.remove('active');
});
// Generate first equation on load
generateBtn.click();
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ffonavia/equationgen" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>