Search code examples
cinfinite-loop

Program to show the process of getting from a 4-digit number to Kaprekar's constant goes on an infinite loop


We are asked to write some code that takes a 4 digit number as input, and does the following:

Take any four-digit number, using at least two different digits.
Arrange the digits in descending and then in ascending order to get two four-digit numbers
Subtract the smaller number from the bigger number.
Go back to step 2 and repeat.

The end result will always freeze at kaprekar's constant 1674 and we must print the algorithm's resulting number each and every time . In the end we also have to print the number of times we had to run the algorithm to get there .

I worked it out as loop , storing the digits in 2 arrays and sorting the first in ascending order and the second in descending order over and over again till i get to 1674 but for some reason the "process" loop won't stop . Any help would be appreciated .

#include <stdio.h>
#include <stdlib.h>

int main()
{
    long int pow1(int x, int n)
    {
        int i, result = 1;
        for (i = 0; i < n; i++)
        { // Power Function //
            result *= x;
        }
        return (result);
    }

    int a, s;
    int val[] = {
        0,
        0,
        0,
        0};
    int value[] = {
        0,
        0,
        0,
        0};
    int ex = 0;
    scanf(" %d", &a);
    if (a / 1000 != 0 && a / 1000 < 10)
    {
        // Extracting the digits and storing them in the arrays .
        for (int i = 0; i <= 3; ++i)
        {
            value[i] = val[i] = (a % pow1(10, i + 1) - a % pow1(10, i)) / pow1(10, i);
            if (i > 0)
            {
                if (val[i] == val[i - 1])
                {
                    ex++;
                }
            }
        }
        if (ex == 3)
        {
            printf("Wrong input");
            exit(0);
        }
        int j = 0, k = a;
        
        // Start of process
        while (k != 6174)
        {
            while (1)
            {
                s = 0;
                for (int i = 0; i <= 3; i++)
                {
                    if (val[i] > val[i + 1])
                    {
                        int temp = val[i];
                        val[i] = val[i + 1];
                        val[i + 1] = temp;
                        s = 1;
                    }
                }
                if (s == 0)
                {
                    break;
                }
            }
            while (1)
            {
                s = 0;
                for (int i = 0; i <= 3; i++)
                {
                    if (value[i] < value[i + 1])
                    {
                        int temp = value[i];
                        value[i] = value[i + 1];
                        value[i + 1] = temp;
                        s = 1;
                    }
                }
                if (s == 0)
                {
                    break;
                }
            }
            j++;
            printf("max:%d min: %d ", value[0] * 1000 + value[1] * 100 + value[2] * 10 + value[3], val[0] * 1000 + val[1] * 100 + val[2] * 10 + val[3]);

            k = value[0] * 1000 + value[1] * 100 + value[2] * 10 + value[3] - (val[0] * 1000 + val[1] * 100 + val[2] * 10 + val[3]);
            printf("diff:%d\n", k);
            for (int i = 0; i <= 3; ++i)
            {
                value[i] = val[i] = (k % pow1(10, i + 1) - k % pow1(10, i)) / pow1(10, i);
            }
        }
        printf("Took %d turns", j);
    }
    else
    {
        printf("Wrong input");
    }

    return 0;
}

Solution

  • You have defined val and value as 4 element [0..3], yet in your loops you access and modify both over [0..4] eg: val[i+1] = temp. I proper sized them (int val[5] = {0}, value[5] = {0}), and your test yielded:

    max:2211 min: 112 diff:2099
    max:9920 min: 229 diff:9691
    max:9961 min: 1699 diff:8262
    max:8622 min: 2268 diff:6354
    max:6543 min: 3456 diff:3087
    max:8730 min: 378 diff:8352
    max:8532 min: 2358 diff:6174
    Took 7 turns
    

    Because your sort isn't quite right. If you change your sort to be:

    for (int i = 1; i < 4; i++)
    {
          if (val[i-1] > val[i])
          {
              int temp = val[i];
              val[i] = val[i - 1];
              val[i - 1] = temp;
              s = 1;
          }
    }
    

    it will respect its boundaries, and be correct; so you can go back to len 4 vectors. Remember to change the other one as well.

    ps: It is more work for me to complain that you didn't put a main wrapper in your example than to put one in. That doesn't excuse not doing the least you can do.