Skill: literal-equations
Practice: Literal Equations
Rearrange formulas for any variable, then put numbers in. Symbolic answers welcome.
1 Practice
Untimed practice with hints and full worked solutions. Every problem is generated fresh.
How to enter answers
- Type the rearranged formula, e.g.
x=(c-b)/a. Spaces are fine. - Use
-for minus,/for division. The*is optional (2A=2*A). - For formula evaluations, enter just the number.
2 Problem types
The generator mixes these types at random.
Solve ax + b = c for x
Subtract q, divide by p.
Solve y = mx + b for x
Isolate x completely.
Two letters
One target, the rest ride along.
Perimeter formula
Divide every term by 2.
Fraction formulas
Clear the denominator first.
Division form
Subtract b, multiply by a.
Evaluate a formula
Substitute, then compute.
// __QCORE_BEGIN__
var QGEN = (function(){
'use strict';
function ri(rng, lo, hi){ return lo + Math.floor(rng() * (hi - lo + 1)); }
function pick(rng, a){ return a[Math.floor(rng() * a.length)]; }
function mhtml(s){ return '' + s + ''; }
var T = [];
function litQ(eq, target, syms, rhs, alts, hint, steps){
var ans = target + '=' + rhs;
return {q:'Solve ' + mhtml(eq) + ' for ' + mhtml(target) + '.',
a:ans, av:null, alt:alts,
data:{kind:'lit', eq:eq, target:target, syms:syms, rhs:rhs},
hint:hint, steps:steps};
}
T.push({id:'solve-axb', name:'Solve ax + b = c for x', level:'easy', gen:function(rng){
return litQ('px + q = r', 'x', ['p', 'q', 'r'], '(r-q)/p',
['(r-q)/p'],
'Subtract q, then divide by p — exactly like numbers.',
['Subtract q: ' + mhtml('px = r − q'),
'Divide by p: x = (r − q)/p.']);
}});
T.push({id:'ymxb', name:'Solve y = mx + b for x', level:'easy', gen:function(rng){
return litQ('y = mx + b', 'x', ['y', 'm', 'b'], '(y-b)/m',
['(y-b)/m'],
'Get mx alone first, then divide by m.',
['Subtract b: ' + mhtml('y − b = mx'),
'Divide by m: x = (y − b)/m.']);
}});
T.push({id:'twoletter', name:'Two letters', level:'medium', gen:function(rng){
var v = pick(rng, [['ax + by = c', 'y', ['a', 'b', 'x', 'c'], '(c-ax)/b', 'Subtract ax, then divide by b.'],
['ax − by = c', 'x', ['a', 'b', 'y', 'c'], '(c+by)/a', 'Add by, then divide by a.']]);
var st1 = v[0] === 'ax + by = c' ? 'Subtract ax: ' + mhtml('by = c − ax') : 'Add by: ' + mhtml('ax = c + by');
var st2 = v[0] === 'ax + by = c' ? 'y = (c − ax)/b.' : 'x = (c + by)/a.';
return litQ(v[0], v[1], v[2], v[3], [v[3]], v[4], [st1, 'Divide: ' + st2]);
}});
T.push({id:'perimeter', name:'Perimeter formula', level:'medium', gen:function(rng){
return litQ('P = 2l + 2w', 'l', ['P', 'l', 'w'], '(P-2w)/2',
['(P-2w)/2'],
'Subtract 2w from both sides, then divide everything by 2.',
['Subtract 2w: ' + mhtml('P − 2w = 2l'),
'Divide by 2: l = (P − 2w)/2.']);
}});
T.push({id:'fraction', name:'Fraction formulas', level:'medium', gen:function(rng){
var v = pick(rng, [['A = bh/2', 'b', ['A', 'b', 'h'], '2A/h', 'Multiply by 2, then divide by h.'],
['V = lwh', 'h', ['V', 'l', 'w', 'h'], 'V/(lw)', 'Divide both sides by lw.']]);
return litQ(v[0], v[1], v[2], v[3], [v[3]], v[4],
['Rearrange to isolate ' + mhtml(v[1]) + '.',
'Answer: ' + v[1] + ' = ' + v[3] + '.']);
}});
T.push({id:'xda', name:'Division form', level:'hard', gen:function(rng){
return litQ('x/a + b = c', 'x', ['x', 'a', 'b', 'c'], 'a(c-b)',
['a(c-b)'],
'Subtract b first, then multiply by a.',
['Subtract b: ' + mhtml('x/a = c − b'),
'Multiply by a: x = a(c − b).']);
}});
T.push({id:'eval', name:'Evaluate a formula', level:'hard', gen:function(rng){
var v = pick(rng, [
{f:'d = rt', vals:{r:ri(rng, 2, 9), t:ri(rng, 2, 9)}, calc:function(v){ return v.r * v.t; }, show:function(v){ return 'd = ' + v.r + ' × ' + v.t; }},
{f:'A = lw', vals:{l:ri(rng, 2, 9), w:ri(rng, 2, 9)}, calc:function(v){ return v.l * v.w; }, show:function(v){ return 'A = ' + v.l + ' × ' + v.w; }},
{f:'P = 2l + 2w', vals:{l:ri(rng, 2, 9), w:ri(rng, 2, 9)}, calc:function(v){ return 2 * v.l + 2 * v.w; }, show:function(v){ return 'P = 2(' + v.l + ') + 2(' + v.w + ')'; }},
{f:'V = lwh', vals:{l:ri(rng, 2, 4), w:ri(rng, 2, 4), h:ri(rng, 2, 4)}, calc:function(v){ return v.l * v.w * v.h; }, show:function(v){ return 'V = ' + v.l + ' × ' + v.w + ' × ' + v.h; }},
{f:'F = ma', vals:{m:ri(rng, 2, 9), a:ri(rng, 2, 9)}, calc:function(v){ return v.m * v.a; }, show:function(v){ return 'F = ' + v.m + ' × ' + v.a; }}
]);
var ans = v.calc(v.vals);
var vstr = Object.keys(v.vals).map(function(k){ return k + ' = ' + v.vals[k]; }).join(', ');
return {q:'Use ' + mhtml(v.f) + ' with ' + mhtml(vstr) + '. Find the unknown value.',
a:String(ans), av:ans, alt:[],
data:{kind:'litnum', f:v.f, vals:v.vals, ans:ans},
hint:'Substitute each number for its letter, then compute.',
steps:['Substitute: ' + mhtml(v.show(v.vals)),
'Answer: ' + ans + '.']};
}});
function norm(s){
return String(s).toLowerCase().replace(/[\s*]/g, '').replace(/−/g, '-').replace(/×/g, '');
}
function checkAnswer(user, canonical, av, alt){
var s = norm(user);
if (s === '') return false;
var cands = [canonical].concat(alt || []);
for (var i = 0; i < cands.length; i++){
if (s === norm(cands[i])) return true;
}
/* also accept with the leading variable dropped: x=(r-q)/p -> (r-q)/p */
var c0 = norm(canonical).replace(/^[a-z]=/, '');
if (s === c0) return true;
if (!/^-?(\d+(\.\d+)?|\.\d+)$/.test(s)) return false;
if (av === null || av === undefined) return false;
return Math.abs(parseFloat(s) - av) < 1e-9;
}
return {templates:T, checkAnswer:checkAnswer};
})();
// __QCORE_END__
/* Shared practice engine (Wave 2C). Requires QGEN global from the skill core. */ (function(){ 'use strict'; var correct = 0, streak = 0, total = 0, attempts = 0, cur = null, curT = null, lastIdx = -1; function $(id){ return document.getElementById(id); } function esc(s){ return String(s).replace(/\x26/g,'&').replace(//g,'>'); } function pickTemplate(){ var Ts = QGEN.templates, i, guard = 0; if (Ts.length === 1) return {t: Ts[0], i: 0}; i = Math.floor(Math.random() * Ts.length); for (guard = 0; guard < 11; guard++){ if (i !== lastIdx) break; i = Math.floor(Math.random() * Ts.length); } lastIdx = i; return {t: Ts[i], i: i}; } function newQuestion(){ var p = pickTemplate(); curT = p.t; cur = curT.gen(Math.random); attempts = 0; $('pType').textContent = curT.name; $('pPrompt').innerHTML = cur.q; $('pAnswer').value = ''; $('pAnswer').disabled = false; $('pCheck').disabled = false; hide($('pFb')); hide($('pHintBox')); hide($('pWhy')); $('pSol').style.display = 'none'; $('pNext').style.display = 'none'; updateStats(); $('pAnswer').focus(); } function show(el){ el.classList.add('show'); } function hide(el){ el.classList.remove('show'); } function updateStats(){ $('pStats').innerHTML = 'Correct ' + correct + ' of ' + total + '' + ' · Streak ' + streak + ''; } function feedback(ok, html){ var f = $('pFb'); f.className = 'fb show ' + (ok ? 'ok' : 'no'); f.innerHTML = html; } function check(){ if (!cur) return; var user = $('pAnswer').value; if (!user.trim()){ feedback(false, 'Enter an answer first.'); return; } var good = false; try { good = QGEN.checkAnswer(user, cur.a, cur.av, cur.alt || []); } catch(e){ good = false; } total++; if (good){ correct++; streak++; feedback(true, 'Correct. ' + esc(cur.a)); showSolution(false); $('pAnswer').disabled = true; $('pCheck').disabled = true; $('pNext').style.display = ''; $('pSol').style.display = 'none'; } else { streak = 0; attempts++; if (attempts >= 2){ feedback(false, 'Not quite. The answer is ' + esc(cur.a) + '. Study the steps below, then try the next one.'); showSolution(true); $('pAnswer').disabled = true; $('pCheck').disabled = true; $('pNext').style.display = ''; } else { feedback(false, 'Not quite — try again. Use the hint if you need it. The answer is ' + esc(cur.a) + ' only after a second miss.'); $('pSol').style.display = ''; } } updateStats(); } function showHint(){ if (!cur) return; var h = $('pHintBox'); h.innerHTML = 'Hint: ' + cur.hint; show(h); } function showSolution(force){ if (!cur) return; var w = $('pWhy'); var lis = cur.steps.map(function(s){ return '
'; }).join(''); w.innerHTML = '
- ' + lis + '
' + '
'; show(w); if (force){ $('pSol').style.display = 'none'; } } document.addEventListener('DOMContentLoaded', function(){ $('pCheck').addEventListener('click', check); $('pAnswer').addEventListener('keydown', function(e){ if (e.key === 'Enter') check(); }); $('pHint').addEventListener('click', showHint); $('pSol').addEventListener('click', function(){ showSolution(false); $('pSol').style.display='none'; }); $('pNext').addEventListener('click', newQuestion); $('pSkip').addEventListener('click', function(){ streak = 0; newQuestion(); }); newQuestion(); }); })();