Spaces:
Running
Running
<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> |