Regrouping for Subtraction with Borrowing (Multi-Digit)
Loading the math board and drawing, please wait…
This GeoGebra lesson demonstrates how to perform multi-digit subtraction (2- and 3-digit numbers) using regrouping/borrowing so that each digit-level calculation stays correct. The key math ideas are place value, column-wise subtraction, and the borrowing chain across tens and hundreds, along with automatic verification of whether the expected borrows occur. Construction and workflow use RandomUniform with saved seeds to generate random problems; digit extraction via numDigits, digitHundredA/B, digitTenA/B, and digitOneA/B; logical branching with If and Take; data assembly with Sequence, Append, Flatten, and Join; and visual/text presentation using TableText, Textfield, and Text (with onboardingTextOffset). UI feedback and layout rely on Element, Max/Min, Translate, and simple geometric objects (Segment/Polygon) while correctness checks compare computed carry/borrow behavior (e.g., carryTens/carryHundreds vs. expectedCarries/carryHundredsOK) to highlight errors. Designed for Grades 4–5 for number-and-word-problem practice, with or without models.
GeoGebra Commands & Parameters
RandomUniform(0, 0.99, 200) → allRandomSeeds, {0.8492057074324373, 0.12433158968830253, 0.34215319866738986, 0.44231459234400966, 0.6473651295467706, 0.8856217160747685, 0.29113570036481773, 0.5157415198272105, 0.8092665561940475, 0.5381847843767462, 0.7952749042456214, 0.04609187862853864, 0.5413256383039124, 0.030850711602795056, 0.21267340908287974, 0.2901949834647718, 0.4322421087107492, 0.7793674680207053, 0.603884506140537, 0.7887210331329008, 0.9876069407078041, 0.6751356793936422, 0.8248243326110102, 0.7176168049138013, 0.7917196495084249, 0.4688903434803698, 0.03467044589428186, 0.5384260621983873, 0.1870975423439892, 0.4335207261654771, 0.43607931334086275, 0.148496586210677, 0.9717193435206259, 0.059075643861563505, 0.5100844160203446, 0.44515178211039624, 0.2720438395433533, 0.3777971767886727, 0.9465036368603207, 0.2219186649541273, 0.5262791950285559, 0.8377577781102008, 0.9525886645283406, 0.989855141396927, 0.3872523888561232, 0.2403460332722683, 0.057991106070516295, 0.5529082816859443, 0.23753811221771737, 0.6694532415014588, 0.33289934724917836, 0.6630609710742653, 0.43125487525005096, 0.30875864682130166, 0.3484166051912927, 0.5987887695335274, 0.21712154109107826, 0.017992603473123994, 0.0839056470970549, 0.9890494414459097, 0.7659904732749755, 0.9194779230614815, 0.2851165427122083, 0.6646662130678725, 0.5831342394316991, 0.37260625302509953, 0.28944402904117345, 0.07954255200527155, 0.2810604466454885, 0.6062017646254244, 0.8106269938465565, 0.1956592957035239, 0.2925653257774814, 0.2169564707240619, 0.6346076965991438, 0.7082565716205362, 0.3961095255863284, 0.14629169816328472, 0.0011093519817628372, 0.6609913062954162, 0.8464097389125678, 0.8581077656978697, 0.5217707292660816, 0.7351877629282921, 0.062388811503254364, 0.19592811705723234, 0.025392800734474537, 0.7825614415492149, 0.05231119120552951, 0.029927803248247762, 0.9240065610072525, 0.2869987137984263, 0.7320549327258961, 0.25225478448353955, 0.3900637922835167, 0.8181127068234463, 0.8770311422308358, 0.9329110458682173, 0.8950806406559428, 0.9473721008477354, 0.9112600312356101, 0.9882547140766904, 0.21353182146080585, 0.18661360357255205, 0.2785485440803763, 0.26991726364307495, 0.7126968237032798, 0.17869949553166814, 0.7505872819966136, 0.3735994458729148, 0.8395013936064804, 0.6909707068551378, 0.3750949364340533, 0.26481726547971207, 0.1191773141934596, 0.28397204516771946, 0.7438868862310932, 0.9722141224544769, 0.3477796895745042, 0.120689343284775, 0.4059297091808886, 0.7985377637326067, 0.17125562507428502, 0.975240499274474, 0.6340667755638437, 0.5148003460917473, 0.4778499217839783, 0.8645996572494968, 0.4561602065486333, 0.3144978490645501, 0.6281625601183358, 0.3025115094687916, 0.9118931527790097, 0.46205925868476233, 0.19813974455699387, 0.0012650028625795873, 0.6454111881142608, 0.7329291430080169, 0.8946845161149596, 0.23444763642475705, 0.6313552020034536, 0.20185667040372937, 0.8914145282363927, 0.8421902666419658, 0.5176485345594986, 0.9710716108682219, 0.9033742485938229, 0.5597379995129623, 0.3626489539139008, 0.21107289273634944, 0.85422532501698, 0.020446873979050855, 0.6469619569542473, 0.5437376998958342, 0.547593362899837, 0.6655070395041174, 0.5413347936799605, 0.1403789764481463, 0.6158409745558905, 0.4948318409837209, 0.8016109704656857, 0.3162364829513284, 0.4845664894783321, 0.2866283078273339, 0.5697233538297015, 0.7976818995225494, 0.2395941846717285, 0.10717828123702239, 0.14613929696002445, 0.5991503029392172, 0.44512667810505585, 0.46731071588670287, 0.31404447890390175, 0.4434807670145869, 0.7070712638564993, 0.6179340430633931, 0.2588622303094726, 0.981956033422562, 0.3443318887830507, 0.28382410629398824, 0.938454055718174, 0.8088761031922224, 0.9430750827473381, 0.2226262187771998, 0.1095314281442766, 0.6099831187726399, 0.8246319738955656, 0.9647318376836743, 0.28443316744076863, 0.8744747035833056, 0.10679121419681811, 0.11932834166093773, 0.10948220231585443, 0.8267005608966846, 0.11076612522602591, 0.5824970163098714, 0.03163446119422874, 0.25593183963525495, 0.17208655617407873, 0.5047476359500183}Take(allRandomSeeds, randIndex, randIndex + numRandoms - 1) → currentRandomSeedsIf(countQuestion ≟ 0, 2, 2 + floor((currentRandomSeeds(1) * 2))) → numDigitsIf(numDigits ≟ 2, 0, 1) → digitHundredBIf(numDigits ≟ 2, 1 + floor((currentRandomSeeds(7) * (digitTenA - 3))), 5 + floor((currentRandomSeeds(7) * 5))) → digitTenBIf(numDigits ≟ 2, 0, digitHundredB + If[carryHundreds, 2, 1] + floor((currentRandomSeeds(2) * 2))) → digitHundredAZip(If[A ≟ B, 0, A], A, reverseSubtract, B, {0, digitHundredA, digitTenA, digitOneA}) → expectedCarriesIf(numDigits ≟ 2, {stringStudentTens, stringStudentUnits, stringCarryTens, stringCarryUnits}, {stringStudentHundreds, stringStudentTens, stringStudentUnits, stringCarryHundreds, stringCarryTens, stringCarryUnits}) → inputCurrentIf((¬fillUnits) ∧ expectedCarries(4) ≠ 0, 3, If[(¬fillTens) ∧ expectedCarries(3) ≠ 0, 2, If[numDigits ≟ 3 ∧ (¬fillHundreds) ∧ expectedCarries(2) ≠ 0, 1, -1]]) → clickIndexAppend(0, Zip[If[Defined[A], A, 0], A, {inputCarryHundreds, inputCarryTens, inputCarryUnits}]) → studentCarriesIf(¬unitsOK, 3, If[¬tensOK, 2, ¬hundredsOK, 1, 0]) → firstErrorIndexZip(A ≠ 0, A, expectedCarries) → expectedSlashesIf(expectedSlashes(3), If[(¬fillTens) ∨ inputCarryTens ≟ 10 + digitTenA, hintTenDouble, If[inputCarryTens ≟ digitTenA - 1, (((("Use place value to help subtract " * digitTenB) * " from ") * (digitTenA - 1)) * ". "), hintTenDouble]]) → hintTensNoCarrySequence((((If[expectedCarries(A) > 0, "\cancel", ""] * "{") * numADigits(A)) * "}"), A, 1, 4) → numASolnCancelPolygon(Zip[PixelsToPoint[Corner[1], Corner[3], Corner[5], A], A, {(pixelsLeft, pixelsTop), (pixelsLeft, y(Corner[5]) - pixelsBottom), Corner[5] - (pixelsRight, pixelsBottom), (x(Corner[5]) - pixelsRight, pixelsTop)}]) → borderBoxCorner(5) → layoutAppSizeonboardingTextOffset(Corner[onboardingText, 1], Corner[onboardingText, 3], onboardingCase, Corner[1], Corner[3], Corner[5]) → OnboardingTextOffsetTextfield(studentHundreds) → inputStudentHundredsTextfield(inputCarryTens) → carryTensBoxTextfield(inputCarryUnits) → carryUnitsBoxTableText(Zip[If[A ≟ 0, "", ("" * A)], A, expectedCarries], numASolnCancel, numBDigits, {"", If[numHundredsSoln > 0, ("" * numHundredsSoln), ""], ("" * ansTens), ("" * ansUnits)}, "c00_00010", 1, 30) → tableAnsTextfield(inputCarryHundreds) → carryHundredsBoxIf(numDigits ≟ 2, (-62, 7), (-55.5, 7)) → AnchorAnsSequence(AnchorAns + ((A * 6.1), 0), A, 0, 3) → allAnsAnchorsZip(A + vTop, A, allAnsAnchors) → allCarryAnchorsTextfield(studentTens) → inputStudentTensTextfield(studentUnits) → inputStudentUnitsPolygon({(0, -8), (0, 25), (6, 25), (6, -8)}) → frameTemplatePolygon({(-3, -3), (-3, 3), (3, 3), (3, -3)}) → clickBoxTemplateZip(A + (2.5, -7.2), A, allCarryAnchors) → allClickAnchorsSequence(Translate[clickBoxTemplate, allClickAnchors(A)], A, If[numDigits ≟ 3, 1, 2], 3) → allClickBoxesZip(If[A, If[B, (((("\textcolor{" * colorRedError) * "}{\cancel{") * C) * "}}"), (((("\textcolor{" * colorRedError) * "}{\cancel{\textcolor{BLACK}{") * C) * "}}}")], (((If[B, (("\textcolor{" * colorRedError) * "}"), ""] * "{") * C) * "}")], A, studentSlashes, B, highlightSlash, C, numADigits) → numAStudentCancelIf(numDigits ≟ 2, 104, 136) → onboardingXIf(showsolution, colorA, colorWhite) → correctColorIf(tensOK, "", If[carryTensOK, hintSubtract, If[¬(expectedSlashes(4)), If[expectedSlashes(3), If[¬fillTens, hintPlaceValue, hintCarry]], hintTensNoCarry]]) → hintTensThreeDigitIf(hundredsOK, "", If[carryHundredsOK, hintSubtract, If[fillHundreds, hintNoUngroup, hintRemaining]]) → hintHundredsIf(unitsOK, "", If[carryUnitsOK, hintSubtract, If[expectedSlashes(4), If[¬(studentSlashes(4)), hintPlaceValue, hintCarry], hintNoUngroup]]) → hintUnitsIf(tensOK, "", If[carryTensOK, hintSubtract, If[fillTens ∧ (¬fillUnits), hintNoUngroup, hintRemaining]]) → hintTensTwoDigitIf(numDigits ≟ 3, hintTensThreeDigit, hintTensTwoDigit) → hintTensElement({hintHundreds, hintTens, hintUnits}, firstErrorIndex) → hintCurrentIf(digitTenA ≥ digitTenB, digitHundredA, digitHundredA - 1) → numHundredsAfterCarryIf(animateControl < startBorrowHundred, 0, If[animateControl > startBorrowHundred + 2, 2, animateControl - startBorrowHundred]) → animateBorrowHundredControlIf(animateBorrowHundredControl < 1, animateBorrowHundredControl, 1) → animateBorrowHundredAMax(0, animateBorrowHundredControl - 1) → animateBorrowHundredBIf(¬carryTens, 0, If[animateControl < 2, animateControl, 2]) → animateBorrowTensControlIf(animateBorrowTensControl < 1, animateBorrowTensControl, 1) → animateBorrowTensAIf(animateBorrowTensControl < 1, 0, animateBorrowTensControl - 1) → animateBorrowTensBIf(carryHundreds, 4, 2) → startCarryHundredsIf(carryTens, 2, 0) → startSubtractUnitsIf(digitHundredB ≟ 0, 0, If[animateControl < startSubtractHundred, 0, If[animateControl > startSubtractHundred + 2, 2, animateControl - startSubtractHundred]]) → animateSubtractHundredControlIf(animateControl < startSubtractTen, 0, If[animateControl > startSubtractTen + 2, 2, animateControl - startSubtractTen]) → animateSubtractTensControlIf(animateControl < startSubtractUnits, 0, If[animateControl > startSubtractUnits + 2, 2, animateControl - startSubtractUnits]) → animateSubtractUnitsControlMax(0, animateSubtractHundredControl - 1) → animateCancelHundredMin(animateSubtractTensControl, 1) → animateCancelTenIf(animateSubtractUnitsControl < 1, animateSubtractUnitsControl, 1) → animateCancelUnitsIf(animateSubtractHundredControl < 1, 0, animateSubtractHundredControl - 1) → animateShowHundredsAnswerMax(0, animateSubtractTensControl - 1) → animateShowTensAnswerIf(animateSubtractUnitsControl < 1, 0, animateSubtractUnitsControl - 1) → animateShowUnitAnswerMin(floor((animateCancelUnits * 10)), digitOneB) → numSlashesIf(digitOneA ≥ digitOneB, digitTenA, digitTenA - 1) → numTensAfterCarryIf(animateBorrowTensControl ≟ 0, digitTenA, numTensAfterCarry) → numTensCurrentFlatten(Sequence[Sequence[AnchorUnits + (3.5, 0) + (((i * 0.25) * blockWidth), ((j * 0.25) * blockWidth)), i, 0, 2], j, 0, 2]) → unitAnchorsJoin({Sequence[AnchorHundreds + (1, 0) + (((i * 1.2) * blockWidth), 0), i, 2, 0, -1], Sequence[AnchorHundreds + (1, (1.2 * blockWidth)) + (((i * 1.2) * blockWidth), 0), i, 2, 0, -1]}) → hundredAnchorsTableText({"\textcolor{#0F8538}{Hundreds}", "\textcolor{#5145A8}{Tens}", "\textcolor{#C75000}{Ones}"}, {"\hspace{250px}", "\hspace{55px}", "\hspace{120px}"}, "c") → backTableCase2Sequence(AnchorTens + (1, 0) + ((((A - 1) * 2.5) * blockWidth / 10), 0), A, 1, 9) → tensAnchorsSequence(cornerBox[blockWidth, blockWidth, hundredAnchors(A) + num2Offset], A, 1, digitHundredB) → hundredsBSequence(cornerBox[blockWidth / 10, blockWidth / 10, unitAnchors(A)], A, 1, digitOneA) → unitsASequence(cornerBox[blockWidth / 10, blockWidth / 10, unitAnchors(A) + num2Offset], A, 1, digitOneB) → unitsBPolygon({AnchorHundreds + (0, -13), AnchorTens + (0, -13), AnchorTens + (0, 23), AnchorHundreds + (0, 23)}) → hundredsBackgroundPolygon({AnchorTens + (0, -13), AnchorUnits + (0, -13), AnchorUnits + (0, 23), AnchorTens + (0, 23)}) → tensBackgroundPolygon({AnchorUnits + (0, -13), AnchorUnits + (11.4, -13), AnchorUnits + (11.4, 23), AnchorUnits + (0, 23)}) → unitsBackgroundSequence(tensAnchors(1) + ((2.5 * (i - 1)), If[digitTenA ≟ 0, 0, 11.2]), i, 1, 10) → borrowAnchorTensSequence(Vector[AnchorTens + (A - 1, 11), borrowAnchorTens(A)], A, 1, 10) → vMoveBorrowHundredsSequence(cornerBox[blockWidth / 10, blockWidth, tensAnchors(A) + num2Offset], A, 1, digitTenB) → tensBSequence(cornerBox[blockWidth, blockWidth, hundredAnchors(A)], A, 1, If[animateBorrowHundredA > 0, numHundredsAfterCarry, digitHundredA]) → hundredsASegment((-0.3, -0.3), (1.3, 1.3)) → slashUnitIf(carryHundreds, Join[{Take[tensAnchors, 1, digitTenA + If[carryTens, -1, 0]], borrowAnchorTens}], tensAnchors) → tensAnchorCurrentSequence(AnchorUnits + (1, ((2.1 * A) * blockWidth / 10)), A, 0, 9) → borrowAnchorUnitsSequence(Vector[AnchorUnits + (0, A - 1), borrowAnchorUnits(A)], A, 1, 10) → vMoveBorrowTensIf(carryTens, Join[{Take[unitAnchors, 1, digitOneA], borrowAnchorUnits}], Reverse[Take[unitAnchors, 1, digitOneA]]) → unitAnchorCurrentSequence(Translate[slashUnit, unitAnchors(A) + num2Offset], A, 1, Min[(animateCancelUnits * 10), digitOneB]) → slashUnitsBTranslate(unitAnchors, Vector[(2 * num2Offset)]) → unitAnchorsSolnTranslate(tensAnchors, Vector[(2 * num2Offset)]) → tensAnchorSolnTranslate(hundredAnchors, Vector[(2 * num2Offset)]) → hundredsAnchorSolnIf(carryTens, Take[unitAnchorCurrent, digitOneB + 1, numUnitsSoln + digitOneB], Reverse[Take[unitAnchorCurrent, digitOneB + 1, numUnitsSoln + digitOneB]]) → moveUnitsStartZip(cornerBox[blockWidth / 10, blockWidth / 10, A + (animateShowUnitAnswer * (B - A))], A, moveUnitsStart, B, unitAnchorsSoln) → movingSolnUnitsTake(tensAnchorCurrent, digitTenB + 1, numTensSoln + digitTenB) → movingTensStartTranslate(tensAnchors, Vector[(2 * num2Offset)]) → tenAnchorsSolnZip(cornerBox[blockWidth / 10, blockWidth, A + (animateShowTensAnswer * (B - A))], A, movingTensStart, B, tenAnchorsSoln) → movingSolnTensTake(hundredAnchors, 1, numHundredsSoln) → movingHundredsStartZip(cornerBox[blockWidth, blockWidth, A + (animateShowHundredsAnswer * (B - A))], B, hundredsAnchorSoln, A, movingHundredsStart) → movingSolnHundredsSegment((-0.4, -0.4), (1.4, 10.4)) → slashTenSegment((-0.5, -0.5), (10.5, 10.5)) → slashHundredTemplateSequence(Translate[slashTen, tensAnchors(A) + num2Offset], A, 1, Min[(animateCancelTen * 10), digitTenB]) → slashTensBSequence(Translate[slashTen, tensAnchorCurrent(A)], A, 1, Min[(animateCancelTen * 10), digitTenB]) → slashTensIf(animateBorrowTensControl < 1, animateBorrowTensControl, 1) → animateBorrowTenATranslate(cornerBox[blockWidth / 10, blockWidth, tensAnchors(digitTenA)], (animateBorrowTenA * (AnchorUnits - tensAnchors(digitTenA)))) → borrowTenAIf(animateBorrowTensControl < 1, 0, animateBorrowTensControl - 1) → animateBorrowTenBZip(cornerBox[blockWidth / 10, blockWidth / 10, AnchorUnits + (0, B) + (animateBorrowTenB * A)], Vector[A], vMoveBorrowTens, B, Sequence[K, K, 0, 9]) → borrowTenBSequence(cornerBox[blockWidth / 10, blockWidth, tensAnchors(A)], A, 1, numTensCurrent) → tensAcornerBox(blockWidth, blockWidth, hundredAnchors(digitHundredA) + (animateBorrowHundredA * (AnchorTens + (0, 11) - hundredAnchors(digitHundredA)))) → borrowHundredASequence(cornerBox[blockWidth / 10, blockWidth, AnchorTens + (A - 1, 11) + (animateBorrowHundredB * vMoveBorrowHundreds(A))], A, 1, 10) → borrowHundredBSequence(Translate[slashUnit, unitAnchorCurrent(A)], A, 1, numSlashes) → slashUnitsTableText({"\textcolor{#5145A8}{Tens}", "\textcolor{#C75000}{Ones}"}, {"\hspace{75px}", "\hspace{80px}"}, "c") → backTableCase1Segment(AnchorHundreds - (0, 1), (x(Vertex[unitsBackground, 2]), y(AnchorHundreds) - 1)) → divisionLineTranslate(slashHundredTemplate, hundredAnchors(If[carryHundreds, digitHundredA - 1, digitHundredA])) → slashHundredsATranslate(slashHundredTemplate, hundredAnchors(digitHundredB) + num2Offset) → slashHundredsBTake(numAStudentCancel, 4 - numDigits) → tableRowAAppend("-", Take[numBDigits, 5 - numDigits]) → tableRowBIf(showsolution, colorB, If[validate, colorC, colorWhite]) → wrongColorcirclePixels(allClickAnchors(clickIndex), 9 + (7 * pulsing), Corner[1], Corner[3], Corner[5]) → pulsingRegroup
AI Drawing Prompt Reference
A graphical interface for multi-digit subtraction practice, featuring input fields for students, an answer display area, and error hint messages. The layout adapts to randomly generated subtraction problems.
The prompt above was compiled from the original drawing commands and is for reference only.