Home > Mobile >  Generate all possible combinations of 3 digits without repetition
Generate all possible combinations of 3 digits without repetition

Time:09-10

I'm trying to write a program that prints all possible combinations of three digits. And there is the constraint that:

  1. The three digits must be different
  2. 012, 120, 102, 021, 201, and 210 are considered the same combination of the three digits 0, 1 and 2
  3. Print only the smallest combination of three digits

The expected output is as follows

012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034, 035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068, 069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138, 139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189, 234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267, 268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368, 369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568, 569, 578, 579, 589, 678, 679, 689, 789

I'm trying to implement in C but the algorithm or any language implementation will suffice.

Here is what I've done so far but it's inacurrate.

#include <stdio.h>

/**
 * main - entry point
 *
 * Description: display triple digits and ,
 *
 * Return: Always 0 (successful)
 */

int main(void)
{
    int i, j, k, l;

    i = 0;
    while (i < 1000)
    {
        j = i / 100; /* hundreds */
        k = (i / 10) % 10; /* tens */
        l = i % 100; /* units */
        if (j < k && k < l)
        {
            putchar(l   '0');
            putchar(k   '0');
            putchar(j   '0');
            if (i < 789)
            {
                putchar(',');
                putchar(' ');
            }
        }
        i  ;
    }
    putchar('\n');

    return (0);
}

CodePudding user response:

Here is a fairly compact snippet of code for giving the smallest unique three-digit number.

#include <stdio.h>

int main()
{
    char digit[4];

    for (int i = 0; i < 8; i  )
    {
        for (int j = i   1; j < 9; j  )
        {
            for (int k = j   1; k < 10; k  )
            {
                digit[0] = i   '0';
                digit[1] = j   '0';
                digit[2] = k   '0';
                digit[3] = '\0';
                printf("%s\n", digit);
            }
        }
    }

    return 0;
}

You can give that a try.

CodePudding user response:

You can do:

#include <stdio.h>

int main (void) {
    char h = '0', t = '1', u = '2';

    while ((h <= '7') || (t <= '8') || (u <= '9')) {
        printf ("%c%c%c, ", h, t, u);
        u != '9' ?   u : (t != '8' ? (  t, u = t   1) : (  h, t = h   1, u = t   1));
    }
    
    return 0;
}

Output:

012, 013, 014, 015, 016, 017, 018, 019, 023, 024, 025, 026, 027, 028, 029, 034,
035, 036, 037, 038, 039, 045, 046, 047, 048, 049, 056, 057, 058, 059, 067, 068,
069, 078, 079, 089, 123, 124, 125, 126, 127, 128, 129, 134, 135, 136, 137, 138,
139, 145, 146, 147, 148, 149, 156, 157, 158, 159, 167, 168, 169, 178, 179, 189,
234, 235, 236, 237, 238, 239, 245, 246, 247, 248, 249, 256, 257, 258, 259, 267,
268, 269, 278, 279, 289, 345, 346, 347, 348, 349, 356, 357, 358, 359, 367, 368,
369, 378, 379, 389, 456, 457, 458, 459, 467, 468, 469, 478, 479, 489, 567, 568,
569, 578, 579, 589, 678, 679, 689, 789,

Explanation:

  • In the program - h, t and u represents digit at hundredth location, digit at tenth location and digit at unit location respectively in a three digit number.

  • Initialised h with '0', t with '1' and u with '2' because 012 is the smallest three digit number without any of the digits being repeated.

  • while loop condition ((h <= '7') || (t <= '8') || (u <= '9')) because 789 is biggest three digit number which follow constraint of - smallest combination of three digits without any of the digits being repeated. Any other combination of 7, 8 and 9 will be bigger than 789 and any three digit number bigger than 789 will violat one of the given constraints.

  • If you find it difficult to understand the expression with ternary operation

          u != '9' ?   u : (t != '8' ? (  t, u = t   1) : (  h, t = h   1, u = t   1));
    

    then here is simplified version using if else :

          if (u != '9') {
                u;
          } else {
              if (t != '8') {
                    t;
                  u = t   1;   // due to given constraint, u will always greater than t
              } else {
                    h;
                  t = h   1;   // due to given constraint, t will always greater than h
                  u = t   1;   // due to given constraint, u will always greater than t
              }
          }
    

CodePudding user response:

Here's some annotated code that might improve the outcome.

char *sep = ""; // the separator to use. Put this line ahead of the loop

and

// meaningful names mean no comment required
// EDIT: thank you, @Chux
int unit = i      % 10;
int tens = i / 10 % 10;
int hund = i /100 % 10;

if ( unit < tens && tens <  hund )
    printf( "%s%c%c%c", sep, hund   '0', tens   '0', unit   '0' ), sep = ", ";

Notice that 'j', 'k' and 'l' have no meaning to this problem. Easy to putchar() the numbers in reverse order without noticing...

Of course, if this is not a homework assignment (Prof wouldn't believe you wrote this)...

#include <stdio.h>

int main() {
    char *sep = "", *dgts = "0123456789";
    for( int h = 0; dgts[h]; h   )
        for( int t = h 1; dgts[t]; t   )
            for( int u = t 1; dgts[u]; u   )
                printf( "%s%c%c%c", sep, dgts[h], dgts[t], dgts[u] ), sep = ", ";
    putchar( '\n' );
    return 0;
}

And, to use the equivalence of array addressing and pointers.

#include <stdio.h>
int main() {
    char *h, *t, *u, *sep = "";
    for( h = "0123456789"; *h; h   )
        for( t = h 1; *t; t   )
            for( u = t 1; *u; u   )
                printf( "%s%c%c%c", sep, *h, *t, *u), sep = ", ";
    putchar( '\n' );
    return 0;
}
  • Related