Find Number Combinations in C#

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 2 Code Examples
digit filtering

What you’ll learn

  • How to list numbers from 1 to a limit that use only two allowed digits (classic demo: 4 and 8).
  • How to peel digits with % 10 and /= 10 inside a reusable helper.
  • Two programs: a fixed reference (limit 500) and a Console input variant with validation.

Overview

This program scans every integer from 1 through a limit and keeps only those whose decimal digits are drawn from a pair you choose. It is a gentle introduction to digit extraction — the same skill used in palindrome, Armstrong, and Harshad checks.

Digit rule

Every digit must equal digit1 or digit2.

Live preview

Try your own digits and limit in the browser.

Classic output

4 & 8 up to 5004 8 44 48 84 88 …

Prerequisites

for loops, while loops, integer division, and the modulo operator %.

  • You understand that num % 10 reads the last digit and num /= 10 removes it.
  • You can write a simple for (int i = 1; i <= limit; i++) loop.

Understanding number combinations

Pick two digits — say 4 and 8. A valid “combination” here is any positive integer built only from those digits.

For limit 500, the list starts 4, 8, 44, 48, 84, 88, 444, 448, 484, 488 and continues while values stay ≤ 500. Numbers like 14 or 80 are rejected because they contain a digit outside the allowed pair.

Valid 48, 88, 444
Invalid 14, 80, 405
Check every digit ∈ {d1, d2}

Quick examples

48 → digits 8, 4 — both allowed. 405 → digit 0 is not 4 or 8, so reject. With digits 1 and 2 up to 25 you get 1 2 11 12 21 22.

Live preview

Enter two allowed digits and an upper limit — the widget runs the same digit-check logic as the C# helper.

Allowed digits

Default matches the reference program: digits 4 and 8, limit 500.

Live result
Press “List combinations”.

Algorithm

Goal: print every integer from 1 to limit whose digits are only digit1 or digit2.

Loop candidates

For each i from 1 to limit, test whether i qualifies.

Peel digits

While num > 0, read digit = num % 10. If it is neither allowed digit, reject i.

Print matches

When every digit passed, write i followed by a space.

📜 Pseudocode

Pseudocode
function usesOnlyDigits(num, d1, d2):
    if num <= 0: return false
    while num > 0:
        digit = num % 10
        if digit != d1 and digit != d2:
            return false
        num = num / 10
    return true

for i from 1 to limit:
    if usesOnlyDigits(i, d1, d2):
        print i
1

Digits 4 and 8 up to 500 (reference)

Classic interview output: list every number from 1 to 500 built only from digits 4 and 8. The helper UsesOnlyAllowedDigits keeps the digit logic in one place.

c#
using System;

class Program
{
    static bool UsesOnlyAllowedDigits(int num, int digit1, int digit2)
    {
        if (num <= 0)
            return false;

        while (num > 0)
        {
            int digit = num % 10;
            if (digit != digit1 && digit != digit2)
                return false;
            num /= 10;
        }
        return true;
    }

    static void GenerateCombinations(int digit1, int digit2, int limit)
    {
        Console.WriteLine($"Numbers using only {digit1} and {digit2} up to {limit}:");

        for (int i = 1; i <= limit; i++)
        {
            if (UsesOnlyAllowedDigits(i, digit1, digit2))
                Console.Write($"{i} ");
        }

        Console.WriteLine();
    }

    static void Main()
    {
        int targetDigit1 = 4;
        int targetDigit2 = 8;
        int combinationLimit = 500;

        GenerateCombinations(targetDigit1, targetDigit2, combinationLimit);
    }
}

How the program works

  1. The outer for loop tries every candidate i from 1 to limit.
  2. UsesOnlyAllowedDigits strips digits from the right; any disallowed digit makes the function return false.
  3. When the helper returns true, every digit was allowed — print i.
2

Read digits and limit from the Console

Same logic with user input. int.TryParse avoids crashes when the user types non-numeric text.

c#
using System;

class Program
{
    static bool UsesOnlyAllowedDigits(int num, int d1, int d2)
    {
        if (num <= 0) return false;
        while (num > 0)
        {
            int digit = num % 10;
            if (digit != d1 && digit != d2) return false;
            num /= 10;
        }
        return true;
    }

    static void Main()
    {
        Console.Write("First allowed digit (0-9): ");
        if (!int.TryParse(Console.ReadLine(), out int d1) || d1 < 0 || d1 > 9)
        {
            Console.WriteLine("Invalid digit.");
            return;
        }

        Console.Write("Second allowed digit (0-9): ");
        if (!int.TryParse(Console.ReadLine(), out int d2) || d2 < 0 || d2 > 9)
        {
            Console.WriteLine("Invalid digit.");
            return;
        }

        Console.Write("Upper limit: ");
        if (!int.TryParse(Console.ReadLine(), out int limit) || limit < 1)
        {
            Console.WriteLine("Limit must be a positive integer.");
            return;
        }

        Console.WriteLine($"Numbers using only {d1} and {d2} up to {limit}:");
        for (int i = 1; i <= limit; i++)
        {
            if (UsesOnlyAllowedDigits(i, d1, d2))
                Console.Write($"{i} ");
        }
        Console.WriteLine();
    }
}

Optimization notes

Generate instead of scan. For very large limits you can build valid numbers recursively (only append d1 or d2) instead of testing every integer — fewer wasted checks.

Keep the helper. One UsesOnlyAllowedDigits method is easier to unit-test than inlined digit loops in multiple places.

❓ FAQ

We list positive integers whose every decimal digit is one of two allowed digits. For 4 and 8 up to 500, valid values include 4, 8, 44, 48, 84, 88, and so on.
No. Textbooks use combination for unordered selections. This interview-style program filters numbers by digit content — a different but common wording on coding sites.
Use num % 10 to read the last digit, then num /= 10 to drop it. Repeat until the number becomes 0.
Zero has no positive digits to inspect in the usual way, and it is not part of the classic output list.
You get only powers-of-ten-style repeats of that digit: 1, 11, 111 when the digit is 1.
Yes. Example 2 reads two digits and a limit with int.TryParse for safe parsing.
O(limit × d) where d is the average number of digits per value — roughly O(limit × log10(limit)).

🔄 Input / output examples

Allowed digitsLimitSample output (start)
4, 85004 8 44 48 84 88 444 448 484 488
1, 2251 2 11 12 21 22
2, 51002 5 22 25 52 55

Edge cases

Zero

Skip non-positive values

Return false for num <= 0 so zero is never printed by mistake.

Same digit

digit1 equals digit2

Still works — you list numbers made of a single repeated digit: 1, 11, 111, …

Limit

Small limits

With limit 3 and digits 4, 8, only 4 qualifies — 8 is excluded because 8 > 3.

⏱️ Time and space complexity

For each of the limit candidates you inspect about log₁₀(i) digits, so total time is O(limit × log limit). Extra space is O(1) aside from console output.

Summary

  • A “number combination” here means digits drawn only from two allowed values.
  • Peel digits with % 10 and /= 10 until the number becomes zero.
  • Loop 1..limit, print every value that passes the digit test.
Did you know?

In this tutorial, a number combination means a positive integer whose decimal digits come only from two allowed digits — not the math formula C(n,r). The classic demo uses digits 4 and 8 up to 500.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

7 people found this page helpful