0

I want to generate numbers 1 to 4 in a random fashion using C programming. I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).

The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).

return apply;

In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.

Problem faced: The number of random numbers generated is varying between 2 and 4. e.g

2 4
2 4 3 
1 3 3 4

etc

Also repetition is there sometimes.

#include <stdio.h>
#include <conio.h>

int checkarray(int *x, int y);

void main() {
    int a[4], i = 0, check;

    srand(time(0));

    while (i < 4) {
        a[i] = rand() % 4 + 1;
        if (i == 0) {
            printf("%d ", a[i]);
            i++;
            continue;
        } else {
            check = checkarray(&a[i], i);
        }
        if (check == 1) {
            printf("\n%d ", a[i]);
        } else {
            continue;
        }
        i++;                    
    }

    getch();
}

int checkarray(int *x, int y) {
    int arrcnt = y, apply = 1, r = 1;
    while (arrcnt > 0) {
        if (*x == *(x - 2 * r)) {
            apply = 0;
            exit(0);
        } else {
            arrcnt--;
            r++;
            continue;
        }
    }   
    return apply;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
Linus
  • 39
  • 4

2 Answers2

1

Let's look at the checkarray function, which is supposed to check if a number is already present in the array.

It is called this way:

check = checkarray(&a[i], i);

Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]

int checkarray(int *x,int y)
{
    int arrcnt=y,apply=1,r=1;
    while(arrcnt>0)
    {
        if(*x==*(x-2*r))
        //         ^^^    Why? This will cause an out of bounds access.
        {
            apply = 0;
            exit(0);    // <-- This ends the program. It should be a 'break;'
        }
        else
        {
            arrcnt--;
            r++;
            continue;
        }
    }   
    return apply;
}

Without changing the interface (which is error prone, in my opinion) it could be rewritten as

int check_array(int *x, int y)
{
    while ( y )
    {
        if ( *x == *(x - y) )   
            return 0;
        --y;
    }
    return 1;
}

Testable here.

There are many other issues which should be addressed, though, so please, take a look to these Q&A too.

Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?

Bob__
  • 12,361
  • 3
  • 28
  • 42
0

Your approach is tedious but can be made to work:

  • there is no need to special case the first number, just make checkarray() return not found for an empty array.
  • you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
  • you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.

Here is a modified version:

#include <stdio.h>
#include <conio.h>

int checkarray(int *array, int len, int value) {
    int i;
    for (i = 0; i < len; i++) {
        if (array[i] == value)
            return 0;
    }
    return 1;
}

int main() {
    int a[4], i = 0, value;

    srand(time(0));

    while (i < 4) {
        value = rand() % 4 + 1;
        if (checkarray(a, i, value)) {
            printf("%d ", value);
            a[i++] = value;
        }
    }
    printf("\n");
    getch();
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189