Regrouping for Subtraction with Borrowing (Multi-Digit)

Regrouping for Subtraction with Borrowing (Multi-Digit)
Loading the math board and drawing, please wait…
2023-10-04 02:27
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

  1. 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}
  2. Take(allRandomSeeds, randIndex, randIndex + numRandoms - 1) → currentRandomSeeds
  3. If(countQuestion ≟ 0, 2, 2 + floor((currentRandomSeeds(1) * 2))) → numDigits
  4. If(numDigits ≟ 2, 0, 1) → digitHundredB
  5. If(numDigits ≟ 2, 1 + floor((currentRandomSeeds(7) * (digitTenA - 3))), 5 + floor((currentRandomSeeds(7) * 5))) → digitTenB
  6. If(numDigits ≟ 2, 0, digitHundredB + If[carryHundreds, 2, 1] + floor((currentRandomSeeds(2) * 2))) → digitHundredA
  7. Zip(If[A ≟ B, 0, A], A, reverseSubtract, B, {0, digitHundredA, digitTenA, digitOneA}) → expectedCarries
  8. If(numDigits ≟ 2, {stringStudentTens, stringStudentUnits, stringCarryTens, stringCarryUnits}, {stringStudentHundreds, stringStudentTens, stringStudentUnits, stringCarryHundreds, stringCarryTens, stringCarryUnits}) → inputCurrent
  9. If((¬fillUnits) ∧ expectedCarries(4) ≠ 0, 3, If[(¬fillTens) ∧ expectedCarries(3) ≠ 0, 2, If[numDigits ≟ 3 ∧ (¬fillHundreds) ∧ expectedCarries(2) ≠ 0, 1, -1]]) → clickIndex
  10. Append(0, Zip[If[Defined[A], A, 0], A, {inputCarryHundreds, inputCarryTens, inputCarryUnits}]) → studentCarries
  11. If(¬unitsOK, 3, If[¬tensOK, 2, ¬hundredsOK, 1, 0]) → firstErrorIndex
  12. Zip(A ≠ 0, A, expectedCarries) → expectedSlashes
  13. If(expectedSlashes(3), If[(¬fillTens) ∨ inputCarryTens ≟ 10 + digitTenA, hintTenDouble, If[inputCarryTens ≟ digitTenA - 1, (((("Use place value to help subtract " * digitTenB) * " from ") * (digitTenA - 1)) * ". "), hintTenDouble]]) → hintTensNoCarry
  14. Sequence((((If[expectedCarries(A) > 0, "\cancel", ""] * "{") * numADigits(A)) * "}"), A, 1, 4) → numASolnCancel
  15. Polygon(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)}]) → borderBox
  16. Corner(5) → layoutAppSize
  17. onboardingTextOffset(Corner[onboardingText, 1], Corner[onboardingText, 3], onboardingCase, Corner[1], Corner[3], Corner[5]) → OnboardingTextOffset
  18. Textfield(studentHundreds) → inputStudentHundreds
  19. Textfield(inputCarryTens) → carryTensBox
  20. Textfield(inputCarryUnits) → carryUnitsBox
  21. TableText(Zip[If[A ≟ 0, "", ("" * A)], A, expectedCarries], numASolnCancel, numBDigits, {"", If[numHundredsSoln > 0, ("" * numHundredsSoln), ""], ("" * ansTens), ("" * ansUnits)}, "c00_00010", 1, 30) → tableAns
  22. Textfield(inputCarryHundreds) → carryHundredsBox
  23. If(numDigits ≟ 2, (-62, 7), (-55.5, 7)) → AnchorAns
  24. Sequence(AnchorAns + ((A * 6.1), 0), A, 0, 3) → allAnsAnchors
  25. Zip(A + vTop, A, allAnsAnchors) → allCarryAnchors
  26. Textfield(studentTens) → inputStudentTens
  27. Textfield(studentUnits) → inputStudentUnits
  28. Polygon({(0, -8), (0, 25), (6, 25), (6, -8)}) → frameTemplate
  29. Polygon({(-3, -3), (-3, 3), (3, 3), (3, -3)}) → clickBoxTemplate
  30. Zip(A + (2.5, -7.2), A, allCarryAnchors) → allClickAnchors
  31. Sequence(Translate[clickBoxTemplate, allClickAnchors(A)], A, If[numDigits ≟ 3, 1, 2], 3) → allClickBoxes
  32. Zip(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) → numAStudentCancel
  33. If(numDigits ≟ 2, 104, 136) → onboardingX
  34. If(showsolution, colorA, colorWhite) → correctColor
  35. If(tensOK, "", If[carryTensOK, hintSubtract, If[¬(expectedSlashes(4)), If[expectedSlashes(3), If[¬fillTens, hintPlaceValue, hintCarry]], hintTensNoCarry]]) → hintTensThreeDigit
  36. If(hundredsOK, "", If[carryHundredsOK, hintSubtract, If[fillHundreds, hintNoUngroup, hintRemaining]]) → hintHundreds
  37. If(unitsOK, "", If[carryUnitsOK, hintSubtract, If[expectedSlashes(4), If[¬(studentSlashes(4)), hintPlaceValue, hintCarry], hintNoUngroup]]) → hintUnits
  38. If(tensOK, "", If[carryTensOK, hintSubtract, If[fillTens ∧ (¬fillUnits), hintNoUngroup, hintRemaining]]) → hintTensTwoDigit
  39. If(numDigits ≟ 3, hintTensThreeDigit, hintTensTwoDigit) → hintTens
  40. Element({hintHundreds, hintTens, hintUnits}, firstErrorIndex) → hintCurrent
  41. If(digitTenA ≥ digitTenB, digitHundredA, digitHundredA - 1) → numHundredsAfterCarry
  42. If(animateControl < startBorrowHundred, 0, If[animateControl > startBorrowHundred + 2, 2, animateControl - startBorrowHundred]) → animateBorrowHundredControl
  43. If(animateBorrowHundredControl < 1, animateBorrowHundredControl, 1) → animateBorrowHundredA
  44. Max(0, animateBorrowHundredControl - 1) → animateBorrowHundredB
  45. If(¬carryTens, 0, If[animateControl < 2, animateControl, 2]) → animateBorrowTensControl
  46. If(animateBorrowTensControl < 1, animateBorrowTensControl, 1) → animateBorrowTensA
  47. If(animateBorrowTensControl < 1, 0, animateBorrowTensControl - 1) → animateBorrowTensB
  48. If(carryHundreds, 4, 2) → startCarryHundreds
  49. If(carryTens, 2, 0) → startSubtractUnits
  50. If(digitHundredB ≟ 0, 0, If[animateControl < startSubtractHundred, 0, If[animateControl > startSubtractHundred + 2, 2, animateControl - startSubtractHundred]]) → animateSubtractHundredControl
  51. If(animateControl < startSubtractTen, 0, If[animateControl > startSubtractTen + 2, 2, animateControl - startSubtractTen]) → animateSubtractTensControl
  52. If(animateControl < startSubtractUnits, 0, If[animateControl > startSubtractUnits + 2, 2, animateControl - startSubtractUnits]) → animateSubtractUnitsControl
  53. Max(0, animateSubtractHundredControl - 1) → animateCancelHundred
  54. Min(animateSubtractTensControl, 1) → animateCancelTen
  55. If(animateSubtractUnitsControl < 1, animateSubtractUnitsControl, 1) → animateCancelUnits
  56. If(animateSubtractHundredControl < 1, 0, animateSubtractHundredControl - 1) → animateShowHundredsAnswer
  57. Max(0, animateSubtractTensControl - 1) → animateShowTensAnswer
  58. If(animateSubtractUnitsControl < 1, 0, animateSubtractUnitsControl - 1) → animateShowUnitAnswer
  59. Min(floor((animateCancelUnits * 10)), digitOneB) → numSlashes
  60. If(digitOneA ≥ digitOneB, digitTenA, digitTenA - 1) → numTensAfterCarry
  61. If(animateBorrowTensControl ≟ 0, digitTenA, numTensAfterCarry) → numTensCurrent
  62. Flatten(Sequence[Sequence[AnchorUnits + (3.5, 0) + (((i * 0.25) * blockWidth), ((j * 0.25) * blockWidth)), i, 0, 2], j, 0, 2]) → unitAnchors
  63. Join({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]}) → hundredAnchors
  64. TableText({"\textcolor{#0F8538}{Hundreds}", "\textcolor{#5145A8}{Tens}", "\textcolor{#C75000}{Ones}"}, {"\hspace{250px}", "\hspace{55px}", "\hspace{120px}"}, "c") → backTableCase2
  65. Sequence(AnchorTens + (1, 0) + ((((A - 1) * 2.5) * blockWidth / 10), 0), A, 1, 9) → tensAnchors
  66. Sequence(cornerBox[blockWidth, blockWidth, hundredAnchors(A) + num2Offset], A, 1, digitHundredB) → hundredsB
  67. Sequence(cornerBox[blockWidth / 10, blockWidth / 10, unitAnchors(A)], A, 1, digitOneA) → unitsA
  68. Sequence(cornerBox[blockWidth / 10, blockWidth / 10, unitAnchors(A) + num2Offset], A, 1, digitOneB) → unitsB
  69. Polygon({AnchorHundreds + (0, -13), AnchorTens + (0, -13), AnchorTens + (0, 23), AnchorHundreds + (0, 23)}) → hundredsBackground
  70. Polygon({AnchorTens + (0, -13), AnchorUnits + (0, -13), AnchorUnits + (0, 23), AnchorTens + (0, 23)}) → tensBackground
  71. Polygon({AnchorUnits + (0, -13), AnchorUnits + (11.4, -13), AnchorUnits + (11.4, 23), AnchorUnits + (0, 23)}) → unitsBackground
  72. Sequence(tensAnchors(1) + ((2.5 * (i - 1)), If[digitTenA ≟ 0, 0, 11.2]), i, 1, 10) → borrowAnchorTens
  73. Sequence(Vector[AnchorTens + (A - 1, 11), borrowAnchorTens(A)], A, 1, 10) → vMoveBorrowHundreds
  74. Sequence(cornerBox[blockWidth / 10, blockWidth, tensAnchors(A) + num2Offset], A, 1, digitTenB) → tensB
  75. Sequence(cornerBox[blockWidth, blockWidth, hundredAnchors(A)], A, 1, If[animateBorrowHundredA > 0, numHundredsAfterCarry, digitHundredA]) → hundredsA
  76. Segment((-0.3, -0.3), (1.3, 1.3)) → slashUnit
  77. If(carryHundreds, Join[{Take[tensAnchors, 1, digitTenA + If[carryTens, -1, 0]], borrowAnchorTens}], tensAnchors) → tensAnchorCurrent
  78. Sequence(AnchorUnits + (1, ((2.1 * A) * blockWidth / 10)), A, 0, 9) → borrowAnchorUnits
  79. Sequence(Vector[AnchorUnits + (0, A - 1), borrowAnchorUnits(A)], A, 1, 10) → vMoveBorrowTens
  80. If(carryTens, Join[{Take[unitAnchors, 1, digitOneA], borrowAnchorUnits}], Reverse[Take[unitAnchors, 1, digitOneA]]) → unitAnchorCurrent
  81. Sequence(Translate[slashUnit, unitAnchors(A) + num2Offset], A, 1, Min[(animateCancelUnits * 10), digitOneB]) → slashUnitsB
  82. Translate(unitAnchors, Vector[(2 * num2Offset)]) → unitAnchorsSoln
  83. Translate(tensAnchors, Vector[(2 * num2Offset)]) → tensAnchorSoln
  84. Translate(hundredAnchors, Vector[(2 * num2Offset)]) → hundredsAnchorSoln
  85. If(carryTens, Take[unitAnchorCurrent, digitOneB + 1, numUnitsSoln + digitOneB], Reverse[Take[unitAnchorCurrent, digitOneB + 1, numUnitsSoln + digitOneB]]) → moveUnitsStart
  86. Zip(cornerBox[blockWidth / 10, blockWidth / 10, A + (animateShowUnitAnswer * (B - A))], A, moveUnitsStart, B, unitAnchorsSoln) → movingSolnUnits
  87. Take(tensAnchorCurrent, digitTenB + 1, numTensSoln + digitTenB) → movingTensStart
  88. Translate(tensAnchors, Vector[(2 * num2Offset)]) → tenAnchorsSoln
  89. Zip(cornerBox[blockWidth / 10, blockWidth, A + (animateShowTensAnswer * (B - A))], A, movingTensStart, B, tenAnchorsSoln) → movingSolnTens
  90. Take(hundredAnchors, 1, numHundredsSoln) → movingHundredsStart
  91. Zip(cornerBox[blockWidth, blockWidth, A + (animateShowHundredsAnswer * (B - A))], B, hundredsAnchorSoln, A, movingHundredsStart) → movingSolnHundreds
  92. Segment((-0.4, -0.4), (1.4, 10.4)) → slashTen
  93. Segment((-0.5, -0.5), (10.5, 10.5)) → slashHundredTemplate
  94. Sequence(Translate[slashTen, tensAnchors(A) + num2Offset], A, 1, Min[(animateCancelTen * 10), digitTenB]) → slashTensB
  95. Sequence(Translate[slashTen, tensAnchorCurrent(A)], A, 1, Min[(animateCancelTen * 10), digitTenB]) → slashTens
  96. If(animateBorrowTensControl < 1, animateBorrowTensControl, 1) → animateBorrowTenA
  97. Translate(cornerBox[blockWidth / 10, blockWidth, tensAnchors(digitTenA)], (animateBorrowTenA * (AnchorUnits - tensAnchors(digitTenA)))) → borrowTenA
  98. If(animateBorrowTensControl < 1, 0, animateBorrowTensControl - 1) → animateBorrowTenB
  99. Zip(cornerBox[blockWidth / 10, blockWidth / 10, AnchorUnits + (0, B) + (animateBorrowTenB * A)], Vector[A], vMoveBorrowTens, B, Sequence[K, K, 0, 9]) → borrowTenB
  100. Sequence(cornerBox[blockWidth / 10, blockWidth, tensAnchors(A)], A, 1, numTensCurrent) → tensA
  101. cornerBox(blockWidth, blockWidth, hundredAnchors(digitHundredA) + (animateBorrowHundredA * (AnchorTens + (0, 11) - hundredAnchors(digitHundredA)))) → borrowHundredA
  102. Sequence(cornerBox[blockWidth / 10, blockWidth, AnchorTens + (A - 1, 11) + (animateBorrowHundredB * vMoveBorrowHundreds(A))], A, 1, 10) → borrowHundredB
  103. Sequence(Translate[slashUnit, unitAnchorCurrent(A)], A, 1, numSlashes) → slashUnits
  104. TableText({"\textcolor{#5145A8}{Tens}", "\textcolor{#C75000}{Ones}"}, {"\hspace{75px}", "\hspace{80px}"}, "c") → backTableCase1
  105. Segment(AnchorHundreds - (0, 1), (x(Vertex[unitsBackground, 2]), y(AnchorHundreds) - 1)) → divisionLine
  106. Translate(slashHundredTemplate, hundredAnchors(If[carryHundreds, digitHundredA - 1, digitHundredA])) → slashHundredsA
  107. Translate(slashHundredTemplate, hundredAnchors(digitHundredB) + num2Offset) → slashHundredsB
  108. Take(numAStudentCancel, 4 - numDigits) → tableRowA
  109. Append("-", Take[numBDigits, 5 - numDigits]) → tableRowB
  110. If(showsolution, colorB, If[validate, colorC, colorWhite]) → wrongColor
  111. circlePixels(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.