Best JavaScript code snippet using fast-check-monorepo
factoring-expressions.js
Source:factoring-expressions.js
1(function() {2 var exprWholeSqrt = function(factors, occFactors) {3 var sqrtOccFactors = KhanUtil.initOccArray(factors.length);4 for (var iFactor = 0; iFactor < factors.length; iFactor++) {5 if (occFactors[iFactor] % 2 !== 0) {6 return undefined;7 }8 sqrtOccFactors[iFactor] = occFactors[iFactor] / 2;9 }10 return KhanUtil.genExprFromExpFactors(factors, sqrtOccFactors);11 //return {op:"^", args:[sqrtExpr, 2]};12 };13 var extractNegativeFactor = function(factors, occFactors) {14 for (var iFactor = 0; iFactor < factors.length; iFactor++) {15 if ((factors[iFactor] === - 1) && (occFactors[iFactor] % 2 === 1)) {16 occFactors[iFactor] = 0;17 return -1;18 }19 }20 return 1;21 };22 var factorDiffOfSquares = function(expr, options) {23 var terms = [];24 for (var iArg = 0; iArg < 2; iArg++) {25 var term = {factors: [], occFactors: []};26 KhanUtil.findExprFactorsExps(expr.args[iArg], {evalBasicNumOps: true}, term.factors, term.occFactors, 1);27 term.prevSign = extractNegativeFactor(term.factors, term.occFactors);28 term.initial = KhanUtil.genExprFromExpFactors(term.factors, term.occFactors);29 term.sqrt = exprWholeSqrt(term.factors, term.occFactors);30 if (term.sqrt === undefined) {31 return undefined;32 }33 term.asSquare = {op: "^", args: [term.sqrt, 2]};34 terms.push(term);35 }36 if ((terms[0].prevSign * terms[1].prevSign) === 1) {37 return undefined;38 }39 var firstTerm = 0;40 if (terms[0].prevSign !== 1) {41 firstTerm = 1;42 }43 var termA = terms[firstTerm];44 var termB = terms[1 - firstTerm];45 //return {op:"-", args:[terms[firstTerm].asSquare, terms[1 - firstTerm].asSquare]};46 var secondTerm = 1 - firstTerm;47 var exprDiff = {op: "-", args: [termA.sqrt, termB.sqrt]};48 var exprSum = {op: "+", args: [termA.sqrt, termB.sqrt]};49 var solution = {op: "*", args: [exprDiff, exprSum]};50 var hints = [];51 if (options.factorDiffOfSquares === "a^2-b^2=(a-b)^2") {52 solution = {op: "^", args: [exprDiff, 2]};53 } else if (options.factorDiffOfSquares === "a^2-b^2=(a-b)(b-a)") {54 solution = {op: "*", args: [exprDiff, {op: "-", args: [termB.sqrt, termA.sqrt]}]};55 } else if (options.factorDiffOfSquares === "a^2-b^2 = (a^2-b^2)(a^2+b^2)") {56 exprDiff = {op: "-", args: [termA.initial, termB.initial]};57 exprSum = {op: "+", args: [termA.initial, termB.initial]};58 solution = {op: "*", args: [exprDiff, exprSum]};59 } else {60 var coloredExpr = {op: "-", args: [KhanUtil.exprSetStyle(termA.initial, KhanUtil.PINK),61 KhanUtil.exprSetStyle(termB.initial, KhanUtil.BLUE)]};62 var initialForm = KhanUtil.parseFormat("#{a^2} - #{b^2}", [KhanUtil.PINK, KhanUtil.BLUE]);63 var factoredForm = KhanUtil.parseFormat("(#a + #b)(#a - #b)", [KhanUtil.PINK, KhanUtil.BLUE, KhanUtil.PINK, KhanUtil.BLUE]);64 hints.push("<p><code>" + KhanUtil.format(coloredExpr) + "</code></p><p>The expression is of the form <code>" + initialForm +65 "</code> which is a difference of two squares so we can factor it as <code>" + factoredForm + "</code></p>");66 var strA = KhanUtil.parseFormat("#a", [KhanUtil.PINK]);67 var strB = KhanUtil.parseFormat("#b", [KhanUtil.BLUE]);68 hints.push("<p>What are the values of <code>" + strA + "</code> and <code>" + strB + "</code>?</p>");69 var varA = {op: "var", args: ["a"]};70 var varB = {op: "var", args: ["b"]};71 var exprA = {op: "=", args: [varA, {op: "sqrt", args: [termA.initial]}, termA.sqrt], style: KhanUtil.PINK};72 var exprB = {op: "=", args: [varB, {op: "sqrt", args: [termB.initial]}, termB.sqrt], style: KhanUtil.BLUE};73 hints.push("<p><code>" + KhanUtil.format(exprA) + "</code><p><code>" + KhanUtil.format(exprB) + "</code></p>");74 hints.push("<p>Use the values we found for <code>" + strA + "</code> and <code>" + strB + "</code> to complete the factored expression, <code>" + factoredForm + "</code></p>");75 var coloredFactored = KhanUtil.exprClone(solution);76 for (var iArg1 = 0; iArg1 < 2; iArg1++) {77 var colors = [KhanUtil.PINK, KhanUtil.BLUE];78 for (var iArg2 = 0; iArg2 < 2; iArg2++) {79 coloredFactored.args[iArg1].args[iArg2] = KhanUtil.exprSetStyle(coloredFactored.args[iArg1].args[iArg2], colors[iArg2]);80 }81 }82 hints.push("<p><b>So we can factor the expression as:</b><code>" + KhanUtil.format(coloredFactored) + "</code>");83 }84 return {solution: solution, hints: hints};85 };86 var fillMissingOccFactors = function(factors, occFactors) {87 for (var iFactor = 0; iFactor < factors.length; iFactor++) {88 if (occFactors[iFactor] === undefined) {89 occFactors[iFactor] = 0;90 }91 }92 }93 var factorSum = function(expr) {94 var factors = [];95 var termsOccFactors = [];96 for (var iArg = 0; iArg < expr.args.length; iArg++) {97 termsOccFactors.push([]);98 var arg = expr.args[iArg];99 KhanUtil.findExprFactorsExps(arg, {evalBasicNumOps: true}, factors, termsOccFactors[iArg], 1);100 }101 for (var iArg = 0; iArg < expr.args.length; iArg++) {102 fillMissingOccFactors(factors, termsOccFactors[iArg]);103 }104 var sharedOccFactors = [];105 var sharedFactors = [];106 for (var iFactor = 0; iFactor < factors.length; iFactor++) {107 var minOcc = Number.MAX_VALUE;108 for (var iTerm = 0; iTerm < termsOccFactors.length; iTerm++) {109 var curOcc = termsOccFactors[iTerm][iFactor];110 if (!KhanUtil.exprIsNumber(curOcc)) {111 alert("Error: not a number");112 }113 curOcc = KhanUtil.exprNumValue(curOcc);114 termsOccFactors[iTerm][iFactor] = curOcc;115 minOcc = Math.min(minOcc, curOcc);116 }117 if (minOcc > 0) {118 sharedFactors.push(iFactor);119 }120 sharedOccFactors.push(minOcc);121 for (var iTerm = 0; iTerm < termsOccFactors.length; iTerm++) {122 termsOccFactors[iTerm][iFactor] -= minOcc;123 }124 }125 return {factors: factors, termsOccFactors: termsOccFactors,126 sharedOccFactors: sharedOccFactors, sharedFactors: sharedFactors};127 };128 var genTermsFactors = function(factors, occFactors, nbTerms, factorsPerTerm, numTotal) {129 var hasNonNumFactor = false;130 var minNumFactor = undefined;131 var maxNumFactor = undefined;132 var excludedFromTerm = [];133 for (var iFactor = 0; iFactor < factors.length; iFactor++) {134 excludedFromTerm[iFactor] = KhanUtil.randRange(0, nbTerms - 1);135 }136 var collidingHashes;137 do {138 var terms = [];139 var termsHashes = {};140 var collidingHashes = false;141 var termsOccFactors = [];142 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {143 var termNumTotal = numTotal;144 termsOccFactors[iTerm] = KhanUtil.initOccArray(factors.length);145 var availableFactors = [];146 var smallestFactorNum = 1000;147 for (var iFactor = 0; iFactor < factors.length; iFactor++) { // TODO : fill that earlier, to avoid extra loop148 if (excludedFromTerm[iFactor] !== iTerm) {149 availableFactors.push(iFactor);150 if (typeof factors[iFactor] !== "number") {151 smallestFactorNum = 0;152 } else {153 smallestFactorNum = Math.min(smallestFactorNum, factors[iFactor]);154 }155 }156 }157 var nbNonShared;158 if (availableFactors.length === 0) {159 nbNonShared = 0;160 } else {161 nbNonShared = KhanUtil.randRange(1, factorsPerTerm);162 }163 var termHash = 0;164 for (var iNonShared = 0; iNonShared < nbNonShared; iNonShared++) {165 if (Math.abs(smallestFactorNum * termNumTotal) > 80) {166 break;167 }168 var iChosen;169 do {170 iChosen = KhanUtil.randFromArray(availableFactors);171 } while ((typeof factors[iChosen] === "number") && (Math.abs(termNumTotal * factors[iChosen]) > 80));172 termHash = termHash * factors.length + iChosen;173 if (typeof factors[iChosen] === "number") {174 termNumTotal *= factors[iChosen];175 minNumFactor = Math.min(factors[iChosen], minNumFactor);176 maxNumFactor = Math.max(factors[iChosen], maxNumFactor);177 } else {178 hasNonNumFactor = true;179 }180 termsOccFactors[iTerm][iChosen]++;181 }182 if (termsHashes[termHash] !== undefined) {183 collidingHashes = true;184 break;185 }186 termsHashes[termHash] = true;187 }188 } while ((!hasNonNumFactor) || (minNumFactor === maxNumFactor) || collidingHashes);189 return termsOccFactors;190 };191 var genAllTermsMarkShared = function(factors, sharedOccFactors, termsOccFactors, colors) {192 var terms = [];193 for (var iTerm = 0; iTerm < termsOccFactors.length; iTerm++) {194 var term = KhanUtil.genExprFromExpFactors(factors, termsOccFactors[iTerm]);195 var sharedTerm = KhanUtil.genExprFromExpFactors(factors, sharedOccFactors);196 if (colors !== undefined) {197 term = KhanUtil.exprSetStyle(term, {color: colors[iTerm]});198 }199 if (sharedTerm !== 1) {200 term = {op: "*", args: [KhanUtil.exprSetStyle(sharedTerm, {color: KhanUtil.BLUE}), term], opsStyles: {symbol: "times"}};201 }202 terms.push(term);203 }204 return terms;205 }206 var genAllTerms = function(factors, sharedOccFactors, termsOccFactors) {207 var terms = [];208 for (var iTerm = 0; iTerm < termsOccFactors.length; iTerm++) {209 var mergedOccFactors = mergeOccFactors(sharedOccFactors, termsOccFactors[iTerm]);210 terms.push(KhanUtil.genExprFromExpFactors(factors, mergedOccFactors));211 }212 return terms;213 };214 var genFullExpr = function(factors, foundOccFactors, termsOccFactors, markShared) {215 var remainingTerms = {op: "+", args: genAllTerms(factors, KhanUtil.initOccArray(factors.length), termsOccFactors)};216 var sharedPart = KhanUtil.genExprFromExpFactors(factors, foundOccFactors);217 if (sharedPart === 1) {218 return remainingTerms;219 }220 if (markShared) {221 sharedPart = KhanUtil.exprSetStyle(sharedPart, {color: KhanUtil.BLUE});222 }223 return {op: "*", args: [sharedPart, remainingTerms]};224 };225 var genFullExprMarkShared = function(factors, foundOccFactors, termsOccFactors, markedFoundOccFactors, markedtermsOccFactors) {226 var remainingTerms = {op: "+", args: genAllTermsMarkShared(factors, markedtermsOccFactors, termsOccFactors)};227 var sharedPart = KhanUtil.genExprFromExpFactors(factors, foundOccFactors);228 var markedPart = KhanUtil.genExprFromExpFactors(factors, markedFoundOccFactors);229 if ((sharedPart === 1) && (markedPart === 1)) {230 return remainingTerms;231 }232 if (sharedPart === 1) {233 sharedPart = KhanUtil.exprSetStyle(markedPart, KhanUtil.BLUE);234 } else if (markedPart !== 1) {235 sharedPart = {op: "*", args: [KhanUtil.exprSetStyle(markedPart, KhanUtil.BLUE), sharedPart], opsStyles: {symbol: "times"}};236 }237 return {op: "*", args: [sharedPart, remainingTerms]};238 };239 var genSharedFactors = function(factors, sharedFactors, occFactors, factorsPerTerm) {240 var nbSharedFactors = KhanUtil.randRange(1, factorsPerTerm);241 var numTotal = 1;242 for (var iFactor = 0; iFactor < nbSharedFactors; iFactor++) {243 var iChosen;244 do {245 iChosen = KhanUtil.randRange(0, factors.length - 1);246 } while ((typeof factors[iChosen] === "number") && (Math.abs(numTotal * factors[iChosen] > 40)));247 if (typeof factors[iChosen] === "number") {248 numTotal *= factors[iChosen];249 }250 occFactors[iChosen]++;251 sharedFactors.push(iChosen);252 }253 return numTotal;254 };255 var genCdotFactors = function(factors, occFactors, sharedOccFactors, sharedStyle) {256 var args = genListFactors(factors, occFactors, sharedOccFactors, sharedStyle);257 var expr;258 if (args.length === 1) {259 return args[0];260 } else {261 var opsStyles = [];262 for (var iOp = 0; iOp < args.length - 1; iOp++) {263 opsStyles.push({symbol: "cdot"});264 }265 return {op: "*", args: args, opsStyles: opsStyles};266 }267 }268 var genDecomposition = function(factors, occFactors, sharedOccFactors, sharedStyle) {269 var exprLeft = KhanUtil.genExprFromExpFactors(factors, occFactors);270 var exprRight = genCdotFactors(factors, occFactors, sharedOccFactors, sharedStyle);271 return {op: "=", args: [exprLeft, exprRight]};272 };273 var genListFactors = function(factors, occFactors, sharedOccFactors, sharedStyle) {274 var listFactors = [];275 for (var iFactor = 0; iFactor < factors.length; iFactor++) {276 for (var iOcc = 0; iOcc < occFactors[iFactor]; iOcc++) {277 var factor = KhanUtil.exprClone(factors[iFactor]);278 if ((sharedOccFactors !== undefined) && (iOcc < sharedOccFactors[iFactor])) {279 factor = KhanUtil.exprSetStyle(factor, sharedStyle);280 }281 listFactors.push(factor);282 }283 }284 return listFactors;285 }286 var genHintListFactors = function(factors, occFactors) {287 var listFactors = genListFactors(factors, occFactors);288 var strListFactors = "";289 for (var iListedFactor = 0; iListedFactor < listFactors.length; iListedFactor++) {290 if (iListedFactor !== 0) {291 if (iListedFactor === listFactors.length - 1) {292 strListFactors += " and ";293 } else {294 strListFactors += ", ";295 }296 }297 strListFactors += "<code>" + KhanUtil.format(KhanUtil.exprSetStyle(listFactors[iListedFactor], {color: KhanUtil.BLUE})) + "</code>";298 }299 var hint = "<span class='factoring-expressions'></span>";300 if (listFactors.length === 1) {301 return hint + "<p>The terms have one common factor: " + strListFactors + ".</p>";302 } else {303 var gcf = KhanUtil.format(KhanUtil.exprSetStyle(KhanUtil.genExprFromExpFactors(factors, occFactors), KhanUtil.BLUE));304 return hint + "<p>The terms have these common factors: " + strListFactors + ", so the greatest common factor is <code>" + gcf + "</code>.</p>";305 }306 };307 var genHintsDecomposeAllFactors = function(factors, sharedOccFactors, termsOccFactors) {308 var colors = [KhanUtil.PINK, KhanUtil.ORANGE, KhanUtil.GREEN];309 var nbTerms = termsOccFactors.length;310 var hints = [];311 var expr = {op: "+", args: genAllTerms(factors, sharedOccFactors, termsOccFactors)};312 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {313 expr.args[iTerm] = KhanUtil.exprSetStyle(expr.args[iTerm], colors[iTerm]);314 }315 expr = KhanUtil.simplify(expr, KhanUtil.simplifyOptions.checkInput);316 hints.push("<p><code>" + KhanUtil.format(expr) + "</code></p><p>We start by decomposing each term into a product of its most simple factors.</p>");317 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {318 var mergedOccFactors = mergeOccFactors(sharedOccFactors, termsOccFactors[iTerm]);319 var hint = "<p class='orig-hint'><code>" + KhanUtil.format(KhanUtil.exprSetStyle(genDecomposition(factors, mergedOccFactors), {color: colors[iTerm]})) + "</code></p>";320 hint += "<p class='new-hint' style='display:none'><code>" + KhanUtil.format(KhanUtil.exprSetStyle(genDecomposition(factors, mergedOccFactors, sharedOccFactors, {color: KhanUtil.BLUE}), {color: colors[iTerm]})) + "</code></p>";321 hints.push(hint);322 }323 hints.push(genHintListFactors(factors, sharedOccFactors));324 hints.push("<p>We can rewrite the expression as: <code>" + KhanUtil.format({op: "+", args: genAllTermsMarkShared(factors, sharedOccFactors, termsOccFactors, colors)}) + "</code>.</p>");325 hints.push("<p>We now rewrite the expression as a product: <code>" + KhanUtil.format(genFullExpr(factors, sharedOccFactors, termsOccFactors, true)) + "</code>.</p>");326 return hints;327 };328 var mergeOccFactors = function(occFactors1, occFactors2) {329 var mergedOccFactors = KhanUtil.initOccArray(occFactors1.length);330 for (var iFactor = 0; iFactor < occFactors1.length; iFactor++) {331 mergedOccFactors[iFactor] = occFactors1[iFactor] + occFactors2[iFactor];332 }333 return mergedOccFactors;334 };335 var removeSharedFactors = function(sharedOccFactors, termsOccFactors) {336 var nbTerms = termsOccFactors.length;337 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {338 for (var iFactor = 0; iFactor < sharedOccFactors.length; iFactor++) {339 termsOccFactors[iTerm][iFactor] -= sharedOccFactors[iFactor];340 }341 }342 };343 var solveDiffOfSquaresExercise = function(expr, options) {344 if (KhanUtil.exprIsNumber(expr) || (expr.args.length != 2)) {345 return undefined;346 }347 if (expr.op === "-") {348 var sumExpr = {op: "+", args: [expr.args[0], {op: "-", args: [expr.args[1]]}]};349 return solveDiffOfSquaresExercise(sumExpr, options);350 }351 return factorDiffOfSquares(expr, options);352 };353 var solveFactoringExercise = function(expr, options) {354 if (options === undefined) {355 options = {};356 }357 expr = KhanUtil.simplify(expr);358 var exprFactors = factorSum(expr);359 var factors = exprFactors.factors;360 var sharedOccFactors = exprFactors.sharedOccFactors;361 var termsOccFactors = exprFactors.termsOccFactors;362 var hints = ["<p>To factor this expression, we start by looking at the different terms of the sum and find all of their common factors. We can then rewrite the expression as a product between these common factors and what's left of the different terms once we remove these factors.</p>"];363 var detailedHints = genHintsDecomposeAllFactors(factors, sharedOccFactors, termsOccFactors);364 var solution = genFullExpr(factors, sharedOccFactors, termsOccFactors);365 if (options.factorDiffOfSquares) {366 var hint = "<p>We obtain the following expression: " + KhanUtil.getSubHints("common-factors", "Show explanation", detailedHints);367 hint += "<p><code>" + KhanUtil.format(solution) + "</code></p>";368 hints.push(hint);369 hints.push("<p>Can we factor this expression even more?</p>");370 for (var iArg = 0; iArg < solution.args.length; iArg++) {371 var arg = solution.args[iArg];372 var solvedArg = solveDiffOfSquaresExercise(arg, options);373 if (solvedArg === undefined) {374 continue;375 }376 hints.push("<p>This part of the expression can be factored: <code>" + KhanUtil.format(arg) + "</code></p>");377 var hint = "<p>We recognize and factor a difference of squares, and obtain the following expression: " + KhanUtil.getSubHints("diff-squares-" + iArg, "Show explanation", solvedArg.hints);378 solution.args[iArg] = solvedArg.solution;379 hint += "<p><code>" + KhanUtil.format(solution);380 hints.push(hint);381 }382 } else {383 hints = hints.concat(detailedHints);384 }385 if (options.factorWithDiffOfSquares === "a(b^2-c^2)=(ab-ac)(a+c))") {386 var exprDiff = solution.args[1].args[0];387 var factor = solution.args[0];388 for (var iArg = 0; iArg < 2; iArg++) {389 exprDiff.args[iArg] = KhanUtil.simplify({op: "*", args: [KhanUtil.exprClone(factor), exprDiff.args[iArg]]},390 {evalBasicNumOps: true});391 }392 solution = solution.args[1];393 } else if (options.factorWithDiffOfSquares === "(ab^2-cd^2)=a(b - d)(b + d)") {394 }395 hints.push("<p class='final_answer'>There is nothing left to factor using this approach. The answer is : <code>" + KhanUtil.format(solution) + "</code></p>");396 return {hints: hints, solution: solution};397 };398 // Generate wrong choices where we put in common a factor that is not shared by all terms399 var genChoicesWithWrongSharedFactor = function(factors, sharedOccFactors, termsOccFactors) {400 var choices = [];401 var nbTerms = termsOccFactors.length;402 var sumNonSharedFactors = KhanUtil.initOccArray(factors.length);403 var bestIFactors = [0, 1];404 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {405 for (var iFactor = 0; iFactor < factors.length; iFactor++) {406 sumNonSharedFactors[iFactor] += termsOccFactors[iTerm][iFactor];407 var curSum = sumNonSharedFactors[iFactor];408 if (curSum > sumNonSharedFactors[bestIFactors[0]]) {409 bestIFactors[1] = bestIFactors[0];410 bestIFactors[0] = iFactor;411 } else if (curSum > sumNonSharedFactors[bestIFactors[1]]) {412 bestIFactors[1] = iFactor;413 }414 }415 }416 for (var iBest = 0; iBest < 2; iBest++) {417 var iFactor = bestIFactors[iBest];418 var savedOccs = [];419 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {420 savedOccs.push(termsOccFactors[iTerm][iFactor]);421 termsOccFactors[iTerm][iFactor] = Math.max(0, termsOccFactors[iTerm][iFactor] - 1);422 }423 sharedOccFactors[iFactor]++;424 choices.push(genFullExpr(factors, sharedOccFactors, termsOccFactors));425 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {426 termsOccFactors[iTerm][iFactor] = savedOccs[iTerm];427 }428 sharedOccFactors[iFactor]--;429 }430 return choices;431 };432 var genChoicesWithMissingSharedFactor = function(factors, sharedOccFactors, termsOccFactors) {433 var choices = [];434 var nbTerms = termsOccFactors.length;435 for (var iFactor = 0; iFactor < factors.length; iFactor++) {436 if (sharedOccFactors[iFactor] <= 0) {437 continue;438 }439 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {440 termsOccFactors[iTerm][iFactor]++;441 }442 sharedOccFactors[iFactor]--;443 badExpr = genFullExpr(factors, sharedOccFactors, termsOccFactors);444 choices.push(badExpr);445 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {446 termsOccFactors[iTerm][iFactor]--;447 }448 sharedOccFactors[iFactor]++;449 }450 return choices;451 };452 // Generate wrong choices where one of the shared factors has been left in one of the terms453 var genChoicesWithExtraFactorInTerm = function(factors, sharedOccFactors, termsOccFactors) {454 var choices = [];455 var nbTerms = termsOccFactors.length;456 for (var iFactor = 0; iFactor < factors.length; iFactor++) {457 if (sharedOccFactors[iFactor] <= 0) {458 continue;459 }460 var badTerm = KhanUtil.randRange(0, nbTerms - 1);461 termsOccFactors[badTerm][iFactor]++;462 badExpr = genFullExpr(factors, sharedOccFactors, termsOccFactors);463 choices.push(badExpr);464 termsOccFactors[badTerm][iFactor]--;465 }466 return choices;467 };468 var genFactoringExercise = function(factors, nbTerms, factorsPerTerm) {469 var sharedFactors = [];470 var sharedOccFactors = KhanUtil.initOccArray(factors.length);471 var numTotal = genSharedFactors(factors, sharedFactors, sharedOccFactors, factorsPerTerm);472 var termsOccFactors = genTermsFactors(factors, sharedOccFactors, nbTerms, factorsPerTerm, numTotal);473 var question = {op: "+", args: genAllTerms(factors, sharedOccFactors, termsOccFactors)};474 var choices = [];475 choices = choices.concat(genChoicesWithMissingSharedFactor(factors, sharedOccFactors, termsOccFactors));476 choices = choices.concat(genChoicesWithExtraFactorInTerm(factors, sharedOccFactors, termsOccFactors));477 choices = choices.concat(genChoicesWithWrongSharedFactor(factors, sharedOccFactors, termsOccFactors));478 return {question: question, choices: choices};479 };480 $.extend(KhanUtil, {481 genFactoringExercise: genFactoringExercise,482 solveFactoringExercise: solveFactoringExercise,483 fillMissingOccFactors: fillMissingOccFactors,484 factorSum: factorSum,485 genFullExpr: genFullExpr486 });487 $.fn["factoring-expressions"] = function(problem) {488 return this.find(".factoring-expressions").addBack().filter(".factoring-expressions").each(function() {489 $(".orig-hint").hide();490 $(".new-hint").show();491 });492 };...
simplifying-expressions.js
Source:simplifying-expressions.js
1(function() {2 var genExprFromOldAndNewOccFactors = function(factors, newOccFactors, oldOccFactors) {3 var colors = [KhanUtil.BLUE, KhanUtil.GREEN, KhanUtil.PINK, KhanUtil.ORANGE];4 var args = [];5 var oldNumFactors = 1;6 var newNumFactors = 1;7 var iColor = 0;8 for (var iFactor = 0; iFactor < factors.length; iFactor++) {9 var factor = factors[iFactor];10 if ((oldOccFactors[iFactor] <= 0) && (newOccFactors[iFactor] <= 0)) {11 continue;12 }13 if (typeof factor === "number") {14 oldNumFactors *= Math.pow(factor, oldOccFactors[iFactor]);15 newNumFactors *= Math.pow(factor, newOccFactors[iFactor]);16 continue;17 }18 if (oldOccFactors[iFactor] === newOccFactors[iFactor]) {19 if (newOccFactors[iFactor] === 1) {20 args.push(factor);21 } else {22 args.push({op: "^", args: [factor, newOccFactors[iFactor]]});23 }24 } else {25 var newArg = factor;26 if (newOccFactors[iFactor] === 0) {27 if (oldOccFactors[iFactor] > 1) {28 newArg = {op: "^", args: [newArg, oldOccFactors[iFactor]]};29 }30 newArg = KhanUtil.exprSetStyle(newArg, {cancel: colors[iColor]});31 iColor++;32 } else {33 var power;34 if (newOccFactors[iFactor] > 1) {35 power = KhanUtil.exprSetStyle(newOccFactors[iFactor], {cancelExpr: oldOccFactors[iFactor]});36 } else {37 power = KhanUtil.exprSetStyle(oldOccFactors[iFactor], {cancel: colors[iColor]});38 iColor++;39 }40 newArg = {op: "^", args: [newArg, power]};41 }42 args.push(newArg);43 }44 }45 if (newNumFactors !== 1) {46 args.unshift(newNumFactors);47 }48 var removedFactors = oldNumFactors / newNumFactors;49 if (removedFactors !== 1) {50 args.unshift(KhanUtil.exprSetStyle(removedFactors, {cancel: colors[iColor]}));51 }52 var expr;53 if (args.length === 0) {54 expr = 1;55 } else if (args.length === 1) {56 expr = args[0];57 } else {58 expr = {op: "*", args: args};59 }60 return expr;61 };62 var getFractionFromOccFactors = function(factors, newTermsOccFactors, oldTermsOccFactors) {63 var newArgs = [];64 for (var iArg = 0; iArg < 2; iArg++) {65 if (oldTermsOccFactors === undefined) {66 newArgs.push(KhanUtil.genExprFromExpFactors(factors, newTermsOccFactors[iArg]));67 } else {68 newArgs.push(genExprFromOldAndNewOccFactors(factors, newTermsOccFactors[iArg], oldTermsOccFactors[iArg]));69 }70 }71 if (KhanUtil.exprIdentical(newArgs[0], newArgs[1]) && (oldTermsOccFactors === undefined)) {72 return 1;73 }74 if (KhanUtil.exprIdentical(newArgs[1], 1)) {75 return newArgs[0];76 }77 return {op: "dfrac", args: newArgs};78 };79 var addInitialSteps = function(steps) {80 var aExpr = {op: "var", args: ["a"]};81 var exampleFactors = [3, 5, aExpr, {op: "var", args: ["b"]}, {op: "var", args: ["c"]}];82 var exampleOldOccs = [[1, 0, 2, 1, 0], [0, 1, 1, 0, 1]];83 var exampleNewOccs = [[1, 0, 1, 1, 0], [0, 1, 0, 0, 1]];84 var exampleExprInit = getFractionFromOccFactors(exampleFactors, exampleOldOccs);85 var exampleExprStep = getFractionFromOccFactors(exampleFactors, exampleNewOccs, exampleOldOccs);86 var exampleExprEnd = getFractionFromOccFactors(exampleFactors, exampleNewOccs);87 var exampleGroup = [KhanUtil.parse("#{\\dfrac{a^2}{a}} &= #{\\dfrac{#{a} \\cdot a}{#{a}}}", [KhanUtil.BLUE, KhanUtil.BLUE, {cancel: true}, {cancel: true}]),88 KhanUtil.parse("&= #{\\dfrac{a}{1}}", [KhanUtil.BLUE]),89 KhanUtil.parse("&= #{a}", [KhanUtil.BLUE])];90 steps.add("<p>To simplify this type of expression, we need to look for factors that are shared by both the numerator and the denominator.</p>For each such factor, if it is present with the same exponent both at the numerator and the denominator, then we can remove that factor completely. If the exponent is different, then we remove the one with the lowest exponent, and substract it from the one with the higher exponent.</p>");91 var subHints = ["<p>Why can we simplify an expression this way? Let's look at the detailed steps that we imply when we write <code>" + KhanUtil.format(exampleExprStep) + "</code> :</p><p><code>" + KhanUtil.format(exampleExprInit) + "</code> can be rewritten as <code>" +92 KhanUtil.parseFormat("\\dfrac{3}{5} \\cdot #{\\dfrac{a^2}{a}} \\cdot b \\cdot \\dfrac{1}{c}", [KhanUtil.BLUE]) + "</code></p><p><code>" +93 KhanUtil.formatGroup(exampleGroup) + "</code></p><p>So we get <code>" +94 KhanUtil.parseFormat("\\dfrac{3}{5} \\cdot #{a} \\cdot b \\cdot \\dfrac{1}{c}", [KhanUtil.BLUE]) + "</code>, or <code>" +95 KhanUtil.parseFormat("\\dfrac{3ab}{5c}") + "</code>"];96 steps.add("<p>For example, if we had this expression: <code>" + KhanUtil.format(exampleExprInit) + "</code>, we would see that the factor <code>" + KhanUtil.format(aExpr) + "</code> is present in both the numerator and the denominator.</p><p>We would then simplify it like this: <code>" + KhanUtil.format(exampleExprStep) + "</code> and obtain: <code>" + KhanUtil.format(exampleExprEnd) + "</code> " + KhanUtil.getSubHints("factoring", "Show explanation", subHints) + "</p><p>Can you apply this technique to this exercise?</p>");97 };98 var factorNumeratorDenominator = function(expr, options, steps) {99 var newArgs = [];100 var wasSimplified = false;101 for (var iArg = 0; iArg < 2; iArg++) {102 var subSteps = new KhanUtil.StepsProblem([0], expr.args[iArg], "simplify by factoring");103 var newArg = KhanUtil.simplify(expr.args[iArg], options, subSteps); // Récupérer les indices104 var termName;105 if (iArg === 0) {106 termName = "numerator";107 } else {108 termName = "denominator";109 }110 if (KhanUtil.stepIsUsed(subSteps)) {111 if (!wasSimplified) {112 steps.add("<p>" + KhanUtil.exprToCode(expr) + "</p>");113 }114 steps.add("<p>We can see that the " + termName + " can be factored some more : " + KhanUtil.exprToCode(expr.args[iArg]) + "<p>");115 steps.add(subSteps);116 steps.add("<p>So the " + termName + " becomes : " + KhanUtil.exprToCode(newArg) + "</p>");117 wasSimplified = true;118 }119 newArgs.push(newArg);120 }121 var newExpr = {op: expr.op, args: newArgs};122 if (wasSimplified) {123 steps.add("<p>We obtain the following expression :</p><p>" + KhanUtil.exprToCode(newExpr));124 }125 return newExpr;126 };127 var solveSimplifyingExpressionsExercise = function(expr) {128 var steps = new KhanUtil.StepsProblem([], expr, "simplify by factoring");129 addInitialSteps(steps);130 var subSteps = new KhanUtil.StepsProblem([], expr, "factor numerator and denominator");131 var options = KhanUtil.simplifyOptions.factor;132 var newExpr = factorNumeratorDenominator(expr, options, subSteps);133 if (KhanUtil.stepIsUsed(subSteps)) {134 steps.add("The first step is to factor the numerator and denominator, if possible : " +135 KhanUtil.getSubHints("factoring-num-denom", "Show explanation", [KhanUtil.genOneHint(subSteps)]) + "</p>" +136 "<p>We obtain : " + KhanUtil.exprToCode(newExpr) + "</p>");137 }138 var factors = [];139 var argsOccFactors = [[], []];140 for (var iArg = 0; iArg < 2; iArg++) {141 KhanUtil.findExprFactorsExps(newExpr.args[iArg], options, factors, argsOccFactors[iArg], 1);142 }143 for (var iArg = 0; iArg < 2; iArg++) {144 KhanUtil.fillMissingOccFactors(factors, argsOccFactors[iArg]);145 }146 var newOccFactors = [[], []];147 for (var iFactor = 0; iFactor < factors.length; iFactor++) {148 var newOcc = argsOccFactors[0][iFactor] - argsOccFactors[1][iFactor];149 newOccFactors[0][iFactor] = 0;150 newOccFactors[1][iFactor] = 0;151 if (newOcc > 0) {152 newOccFactors[0][iFactor] = newOcc;153 } else {154 newOccFactors[1][iFactor] = -newOcc;155 }156 }157 var solExpr = getFractionFromOccFactors(factors, newOccFactors);158 var choices = [];159 for (var iFactor = 0; iFactor < factors.length; iFactor++) {160 var sideMax = 0;161 if (argsOccFactors[0][iFactor] < argsOccFactors[0][iFactor]) {162 sideMax = 1;163 }164 if (newOccFactors[sideMax][iFactor] > 0) {165 newOccFactors[sideMax][iFactor]--;166 choices.push(KhanUtil.exprClone(getFractionFromOccFactors(factors, newOccFactors)));167 newOccFactors[sideMax][iFactor]++;168 }169 newOccFactors[1 - sideMax][iFactor]++;170 choices.push(KhanUtil.exprClone(getFractionFromOccFactors(factors, newOccFactors)));171 newOccFactors[1 - sideMax][iFactor]--;172 }173 var hintExpr = getFractionFromOccFactors(factors, newOccFactors, argsOccFactors);174 if (KhanUtil.exprIdentical(newExpr, solExpr)) {175 steps.add("<p class='final_answer'>There are no factors that can be simplified in this expression, so the answer is: <code>" + KhanUtil.format(solExpr) + "</code>");176 } else {177 steps.add("<p>Applying the approach described above gives in this case:</p><p><code>" + KhanUtil.format(hintExpr) + "</code></p>");178 steps.add("<p class='final_answer'>We obtain the following expression:</p><p><code>" + KhanUtil.format(solExpr) + "</code></p>");179 }180 var hints = KhanUtil.genHints(steps);181 return {solution: solExpr, hints: hints, choices: choices};182 };183 var getNonNumNonVarIFactors = function(factors, occFactors) {184 var listIFactors = [];185 var lastNumOrVarIFactor;186 for (var iFactor = 0; iFactor < occFactors.length; iFactor++) {187 for (var iOcc = 0; iOcc < occFactors[iFactor]; iOcc++) {188 var factor = factors[iFactor];189 if ((!KhanUtil.exprIsNumber(factor)) && (factor.op !== "var")) {190 listIFactors.push(iFactor);191 } else {192 lastNumOrVarIFactor = iFactor;193 }194 }195 }196 if (listIFactors.length === 0) {197 listIFactors.push(lastNumOrVarIFactor);198 }199 return listIFactors;200 };201 var genSimplifyingExpressionsExercise = function(nbTerms, maxPower, numFactors, variables, types, withInnerFactor) {202 var factors = [];203 for (var iTerm = 0; iTerm < nbTerms; iTerm++) {204 var term;205 do {206 var type = KhanUtil.randFromArray(types);207 switch (type) {208 case 0:209 term = KhanUtil.randFromArray(variables);210 break;211 case 1:212 var variable = KhanUtil.randFromArray(variables);213 var cst = KhanUtil.randRange(1, 5);214 term = {op: "+", args: [variable, cst]};215 break;216 case 2:217 var variable = KhanUtil.randFromArray(variables);218 var cst = KhanUtil.randRange(1, 5);219 term = {op: "-", args: [variable, cst]};220 break;221 case 3:222 term = KhanUtil.randFromArray(numFactors);223 break;224 }225 } while (KhanUtil.exprInList(factors, term));226 factors.push(term);227 }228 var sidesOccFactors = [KhanUtil.initOccArray(factors.length), KhanUtil.initOccArray(factors.length)];229 var sidesIFactors = [[], []];230 var extraCommonNum = 1;231 if (withInnerFactor) {232 extraCommonNum = KhanUtil.randFromArray(numFactors);233 }234 var topNum = 1;235 var downNum = 1;236 for (var iFactor = 0; iFactor < factors.length; iFactor++) {237 var factor = factors[iFactor];238 var curMaxPower = maxPower;239 if (KhanUtil.exprIsNumber(factor)) {240 curMaxPower = Math.min(curMaxPower, 2);241 }242 var forbiddenSide = KhanUtil.randRange(0, 2);243 var topPower = KhanUtil.randRange(1, maxPower);244 var downPower = KhanUtil.randRange(1, maxPower);245 if (forbiddenSide === 0) {246 topPower = 0;247 } else if (forbiddenSide === 1) {248 downPower = 0;249 }250 if (KhanUtil.exprIsNumber(factor)) {251 while (Math.abs(extraCommonNum * topNum * Math.pow(factor, topPower) > 80)) {252 topPower--;253 }254 while (Math.abs(extraCommonNum * downNum * Math.pow(factor, downPower) > 80)) {255 downPower--;256 }257 topNum *= Math.pow(factor, topPower);258 downNum *= Math.pow(factor, downPower);259 }260 sidesOccFactors[0][iFactor] = topPower;261 sidesOccFactors[1][iFactor] = downPower;262 }263 if (extraCommonNum !== 1) {264 var sidesIFactors = [];265 for (var iSide = 0; iSide < 2; iSide++) {266 sidesIFactors.push(getNonNumNonVarIFactors(factors, sidesOccFactors[iSide]));267 }268 for (var iSide = 0; iSide < 2; iSide++) {269 var pickedFactor = KhanUtil.randFromArray(sidesIFactors[iSide]);270 sidesOccFactors[iSide][pickedFactor]--;271 var factor = {op: "*", args: [extraCommonNum, KhanUtil.exprClone(factors[pickedFactor])]};272 factor = KhanUtil.simplify(factor, {evalBasicNumOps: true, expandProducts: true});273 factors.push(factor);274 sidesOccFactors[iSide].push(1);275 sidesOccFactors[1 - iSide].push(0);276 }277 }278 var exprArgs = [];279 for (var iSide = 0; iSide < 2; iSide++) {280 exprArgs.push(KhanUtil.genExprFromExpFactors(factors, sidesOccFactors[iSide]));281 }282 return {op: "dfrac", args: exprArgs};283 };284 $.extend(KhanUtil, {285 genSimplifyingExpressionsExercise: genSimplifyingExpressionsExercise,286 solveSimplifyingExpressionsExercise: solveSimplifyingExpressionsExercise287 });...
primefactors.js
Source:primefactors.js
1function primeFactors(number) {2 var factors = [];3 var divisor = 2;4 while(number > 1) {5 if(number % divisor == 0) {6 factors.push(divisor);7 number = number / divisor;8 } else {9 divisor++;10 }11 }12 return factors;13}14var test = require('unit.js');15describe('Test numbers', function(){16 it ("1", function() { primeFactors(1).must.be.eql([]); });17 it ("2", function() { primeFactors(2).must.be.eql([2]); });18 it ("3", function() { primeFactors(3).must.be.eql([3]); });19 it ("4", function() { primeFactors(4).must.be.eql([2,2]); });20 it ("5", function() { primeFactors(5).must.be.eql([5]); });21 it ("6", function() { primeFactors(6).must.be.eql([2,3]); });22 it ("7", function() { primeFactors(7).must.be.eql([7]); });23 it ("8", function() { primeFactors(8).must.be.eql([2,2,2]); });24 it ("9", function() { primeFactors(9).must.be.eql([3,3]); });25 it ("10", function() { primeFactors(10).must.be.eql([2,5]); });26 it ("11", function() { primeFactors(11).must.be.eql([11]); });27 it ("12", function() { primeFactors(12).must.be.eql([2,2,3]); });28 it ("13", function() { primeFactors(13).must.be.eql([13]); });29 it ("14", function() { primeFactors(14).must.be.eql([2,7]); });30 it ("15", function() { primeFactors(15).must.be.eql([3,5]); });31 it ("16", function() { primeFactors(16).must.be.eql([2,2,2,2]); });32 it ("17", function() { primeFactors(17).must.be.eql([17]); });33 it ("18", function() { primeFactors(18).must.be.eql([2,3,3]); });34 it ("19", function() { primeFactors(19).must.be.eql([19]); });35 it ("20", function() { primeFactors(20).must.be.eql([2,2,5]); });36 it ("21", function() { primeFactors(21).must.be.eql([3,7]); });37 it ("22", function() { primeFactors(22).must.be.eql([2,11]); });38 it ("25", function() { primeFactors(25).must.be.eql([5,5]); });39 it ("35", function() { primeFactors(35).must.be.eql([5,7]); });...
Using AI Code Generation
1const fc = require("fast-check");2fc.assert(3 fc.property(fc.integer(), fc.integer(), (a, b) => {4 return a * b === b * a;5 })6);
Using AI Code Generation
1const { factors } = require('fast-check-monorepo');2const { factors } = require('fast-check-monorepo');3const { factors } = require('fast-check-monorepo');4const { factors } = require('fast-check-monorepo');5const { factors } = require('fast-check-monorepo');6const { factors } = require('fast-check-monorepo');7const { factors } = require('fast-check-monorepo');8const { factors } = require('fast-check-monorepo');9const { factors } = require('fast-check-monorepo');10const { factors } = require('fast-check-monorepo');11const { factors } = require('fast-check-monorepo');12const { factors } = require('fast-check-monorepo');13const { factors } = require('fast-check-monorepo');14const { factors } = require('fast-check-monorepo');15const { factors } = require('fast-check-monorepo');16const { factors } = require('fast-check-mon
Using AI Code Generation
1const fc = require('fast-check');2const { factors } = require('fast-check-monorepo');3const isPrime = (n) => {4 for (let i = 2; i < n / 2; i++) {5 if (n % i === 0) {6 return false;7 }8 }9 return true;10};11fc.assert(12 fc.property(13 fc.nat(),14 (n) => {15 if (n < 2) {16 return true;17 }18 const factorsOfN = factors(n);19 return factorsOfN.reduce((a, b) => a * b) === n;20 },21 { verbose: true },22);23const fc = require('fast-check');24const { factors } = require('fast-check-monorepo');25const isPrime = (n) => {26 for (let i = 2; i < n / 2; i++) {27 if (n % i === 0) {28 return false;29 }30 }31 return true;32};33fc.assert(34 fc.property(35 fc.nat(),36 (n) => {37 if (n < 2) {38 return true;39 }40 const factorsOfN = factors(n);41 return factorsOfN.reduce((a, b) => a * b) === n;42 },43 { verbose: true },44);45const fc = require('fast-check');46const { factors } = require('fast-check-monorepo');47const isPrime = (n) => {48 for (let i = 2; i < n / 2; i++) {49 if (n % i === 0) {50 return false;51 }52 }53 return true;54};55fc.assert(56 fc.property(57 fc.nat(),58 (n) => {59 if (n < 2) {60 return true;61 }62 const factorsOfN = factors(n);63 return factorsOfN.reduce((a, b) => a * b) === n;64 },65 { verbose: true },66);67const fc = require('fast-check');68const { factors } = require('fast-check-monorepo');69const isPrime = (n) => {70 for (let i = 2; i < n
Using AI Code Generation
1const fc = require('fast-check');2const factors = require('fast-check-monorepo').factors;3fc.assert(4 fc.property(fc.integer(), (n) => {5 const factorization = factors(n);6 return factorization.reduce((p, c) => p * c, 1) === n;7 })8);
Using AI Code Generation
1const {factors} = require('fast-check');2const factorsOf5 = factors(5);3console.log(factorsOf5);4const factorsOf6 = factors(6);5console.log(factorsOf6);6const factorsOf7 = factors(7);7console.log(factorsOf7);8const {factors} = require('fast-check');9const factorsOf5 = factors(5);10console.log(factorsOf5);11const factorsOf6 = factors(6);12console.log(factorsOf6);13const factorsOf7 = factors(7);14console.log(factorsOf7);15const {factors} = require('fast-check');16const factorsOf5 = factors(5);17console.log(factorsOf5);
Using AI Code Generation
1const {factors} = require('fast-check-monorepo');2const {property} = require('fast-check');3property(factors(), (factors) => {4 return true;5});6const {factors} = require('fast-check-monorepo');7const {property} = require('fast-check');8property(factors(), (factors) => {9 return true;10});
Using AI Code Generation
1const fc = require("fast-check");2const {isPrime} = require("./test1");3const test1 = fc.property(fc.integer(1, 1000), (n) => {4 return isPrime(n);5});6test1.check(1000);7const test2 = fc.property(fc.integer(1, 1000), (n) => {8 return isPrime(n);9});10test2.check(1000);11const test3 = fc.property(fc.integer(1, 1000), (n) => {12 return isPrime(n);13});14test3.check(1000);15const test4 = fc.property(fc.integer(1, 1000), (n) => {16 return isPrime(n);17});18test4.check(1000);19const test5 = fc.property(fc.integer(1, 1000), (n) => {20 return isPrime(n);21});22test5.check(1000);23const test6 = fc.property(fc.integer(1, 1000), (n) => {24 return isPrime(n);25});26test6.check(1000);27const test7 = fc.property(fc.integer(1, 1000), (n) => {28 return isPrime(n);29});30test7.check(1000);31const test8 = fc.property(fc.integer(1, 1000), (n) => {32 return isPrime(n);33});34test8.check(1000);35const test9 = fc.property(fc.integer(1, 1000), (n) => {36 return isPrime(n);37});38test9.check(1000);39const test10 = fc.property(fc.integer(1, 1000), (n) => {40 return isPrime(n);41});42test10.check(1000);43const test11 = fc.property(fc.integer(1, 1000), (n) => {44 return isPrime(n);45});46test11.check(1000);
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!