Lesson 22 of 50 intermediate

Playing with Digits

Extract, count, sum, and reverse digits — essential tricks for number-based problems!

Open interactive version (quiz + challenge)

Real-world analogy

Think of a number like 4827 as beads on an abacus — each bead represents one digit. You can count the beads (4 digits), add them up (4+8+2+7=21), rearrange them backwards (7284), or check if the pattern reads the same both ways (like 1221). The two magic operations are: %10 grabs the last bead (the ones digit), and /10 removes the last bead. With just these two moves, you can take apart any number and play with its pieces!

What is it?

Playing with digits means breaking a number into its individual digits and performing operations on them. The two key operations are: n % 10 (extract the last digit) and n / 10 (remove the last digit). By repeating these in a loop, you can count digits, sum them, reverse the number, check for palindromes, and solve many number theory problems in competitive programming.

Real-world relevance

Digit manipulation shows up everywhere: credit card validation (the Luhn algorithm sums digits), ISBN book number verification, digital clocks, odometers in cars, and many CP problems. When an ATM counts money or a calculator displays a result, digit manipulation is happening behind the scenes.

Key points

Code example

#include <bits/stdc++.h>
using namespace std;

// Count digits in a number
int countDigits(int n) {
    if (n == 0) return 1;
    int count = 0;
    while (n > 0) {
        count++;
        n /= 10;
    }
    return count;
}

// Sum of digits
int digitSum(int n) {
    int sum = 0;
    while (n > 0) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}

// Reverse a number
int reverseNum(int n) {
    int rev = 0;
    while (n > 0) {
        rev = rev * 10 + n % 10;
        n /= 10;
    }
    return rev;
}

// Check if number is palindrome
bool isPalindromeNum(int n) {
    return n == reverseNum(n);
}

int main() {
    int n;
    cin >> n;
    
    cout << "Number: " << n << endl;
    cout << "Digits: " << countDigits(n) << endl;
    cout << "Digit sum: " << digitSum(n) << endl;
    cout << "Reversed: " << reverseNum(n) << endl;
    
    if (isPalindromeNum(n)) {
        cout << n << " is a palindrome!" << endl;
    } else {
        cout << n << " is NOT a palindrome." << endl;
    }
    
    // Bonus: extract all digits into a vector
    vector<int> digits;
    int temp = n;
    while (temp > 0) {
        digits.push_back(temp % 10);
        temp /= 10;
    }
    reverse(digits.begin(), digits.end());
    
    cout << "Individual digits: ";
    for (int d : digits) cout << d << " ";
    cout << endl;
    
    return 0;
}

Line-by-line walkthrough

  1. 1. while (n > 0) { count++; n /= 10; } — Each time we divide n by 10, we remove one digit and increment our counter. When n becomes 0, we have counted all digits. We handle n=0 specially because the loop would not execute.
  2. 2. sum += n % 10; n /= 10; — First we grab the last digit (n%10) and add it to sum. Then we remove that digit (n/=10). Repeat until n is 0. For 1234: we get 4, then 3, then 2, then 1.
  3. 3. rev = rev * 10 + n % 10; — This is the clever digit-building formula. rev*10 shifts all existing digits one place left (making room for a new digit on the right). Then + n%10 places the extracted digit in that new spot. For 1234: rev goes 0→4→43→432→4321.
  4. 4. return n == reverseNum(n); — To check palindrome, we reverse the number and compare with the original. If they are equal, the number reads the same both ways. Clean and simple!
  5. 5. digits.push_back(temp % 10); — We extract digits one by one and store them in a vector. They come out in reverse order (4,3,2,1 for 1234), so we reverse the vector at the end to get them in the right order (1,2,3,4).

Spot the bug

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    // Try to count digits and sum them
    int count = 0, sum = 0;
    while (n > 0) {
        sum += n % 10;
        n /= 10;
        count++;
    }
    
    // Now try to reverse n
    int rev = 0;
    while (n > 0) {
        rev = rev * 10 + n % 10;
        n /= 10;
    }
    
    cout << "Digits: " << count << endl;
    cout << "Sum: " << sum << endl;
    cout << "Reversed: " << rev << endl;
    return 0;
}
Need a hint?
After the first while loop finishes, what is the value of n? When the second while loop starts, what does it try to work with?
Show answer
The bug is that the first while loop destroys n — after counting digits and summing them, n is 0. So the second while loop never executes (0 > 0 is false), and rev stays 0! The fix: save the original value before the first loop: int original = n; Then use original for the second loop (or use a separate variable). Always save a copy of your number before destroying it in a while loop!

Explain like I'm 5

Imagine you have the number 352 written on cards — one card says 3, one says 5, one says 2. The trick %10 is like peeking at the last card (2). The trick /10 is like removing the last card, leaving you with 35. You keep peeking and removing until all cards are gone. Meanwhile, you can count the cards, add up the numbers, or put them back in reverse order. That is all digit manipulation is — playing with number cards one at a time!

Fun fact

The number 1089 has a magical property with digit reversal: take any 3-digit number where the first digit is bigger than the last (like 532). Reverse it (235). Subtract the smaller from the bigger (532-235=297). Now reverse the result (792). Add them (297+792=1089). You ALWAYS get 1089! Try it with any valid 3-digit number — it works every time!

Hands-on challenge

Read a number n. Print: (1) the number of digits, (2) the sum of digits, (3) the reverse of the number, (4) whether it is a palindrome (YES or NO). Then print the product of all digits and the largest single digit in the number.

More resources

Open interactive version (quiz + challenge) ← Back to course: CP Zero to Hero