I have written a code for randomly printing a number from 1 to 10 without any repetition, but it isn't working properly sometimes I get the number that is already written.
In short, I'm trying to print numbers from 1-10 randomly with no repetition.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
main() {
int no = 0, repeat[100] = { 0 }, i = 0, x = 0, j = 0;
srand(time(NULL));
while (true) {
no = (rand() % 10) + 1;
for (i = 0; i < 100; i++) {
if (no != repeat[i]) {
x = 1;
} else if (no == repeat[i]) {
x = 0;
}
}
if (x == 1) {
repeat[j] = no;
printf("\n%d", repeat[i]);
j = j + 1;
}
getch();
}
}
Don't use rand() to generate the numbers directly, instead fill a sequential array, and then use rand() to shuffle the array, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/** shuffle integer array of size 'n'
* (using fisher-yates method)
*/
void shuffle (int *a, int n)
{
int i, tmp;
while (n-- > 1) {
i = rand() % (n + 1);
tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
}
int main (void) {
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
srand (time(NULL));
shuffle (arr, 10);
for (int i = 0; i < 10; i++)
printf (" %d", arr[i]);
putchar ('\n');
}
By shuffling the array and swapping random elements within it, you eliminate all possibility of a duplicate number.
Example Use/Output
$ ./bin/shuffle_arr
3 10 7 8 4 5 6 9 1 2
#include <stdio.h>
#define N1 1
#define N2 10
void main() {
int len = N2 - N1 + 1, i, r, temp;
int num[len];
//Fill array with numbers
for (temp = 0, i = N1; temp < len; i++, temp++)
num[temp] = i;
srand(time(NULL));
for (i = len - 1; i > 0; i--) {
r = rand() % i; //pop random number
//swaping
temp = num[i];
num[i] = num[r];
num[r] = temp;
}
/*Random Numbers are stored in Array*/
//print that array
for (i = 0; i < len; i++)
printf("%d\n", num[i]);
}
Related
I have written this code in order to implement the Counting Sort in C. However it does not seem working properly.
I create an array of 10 elements and then I apply the steps of counting sort. Basically it orders the first elements, and then as last elements it uses the last elements of the original array. I am not understanding where is the problem.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// create an array of 100 random elements
// int my_array[10];
int my_array[] = { 10, 10, 9, 9, 6, 5, 4, 3, 2, 1 };
srand(time(NULL));
int i;
int N = 10;
/* for (i = 0; i < 10; i++) {
my_array[i] = rand() % 100 + 1;
} */
// print the array
for (i = 0; i < 10; i++) {
printf("%d\n", my_array[i]);
}
// define the minimum and the maximum as the first element of the array
int min_array = my_array[0];
int max_array = my_array[0];
printf("--------------\n");
// find the minimum and the maximum of the array
for (i = 0; i < N; i++) {
if (my_array[i] < min_array) {
min_array = my_array[i];
}
else if (my_array[i] > max_array) {
max_array = my_array[i];
}
}
// check if it worked
printf("max_array %d\n", max_array);
printf("min_array %d\n", min_array);
//
int range_array;
range_array = max_array - min_array + 1;
int count_array[range_array + 1];
for (i = 0; i < range_array; i++)
count_array[i] = 0;
int j = 0;
for (int i = 0; i < 10; i++) {
count_array[my_array[i] - min_array] = count_array[my_array[i] - min_array] + 1;
}
int z = 0;
for (i = min_array; i < max_array; i++) {
for (j = 0; j < count_array[i - min_array]; j++)
my_array[z++] = i;
// z = z + 1;
}
for (i = 0; i < N; i++) {
printf("%d\n", my_array[i]);
}
}
And one possible output:
10 10 9 9 6 5 4 3 2 1
--------------
max_array 10
min_array 1
--------------
1 2 3 4 5 6 9 9 2 1
So as you can see the numbers from 1 to 9 are ordered, while the last one, 10, is not ordered, and it uses the first numbers, so 1 and 2.
When rebuilding the array, you want to include the elements with a value of max_array.
i<max_array
should be
i<=max_array
As a side note, you never use the last element of count_array, so it should be one element smaller.
int count_array[range_array + 1];
should be
int count_array[range_array];
(Spotted by #user3386109)
How to separate the even position number of an array from the odd position number in C.
Example
int arr[]= {2,3,4,5,6,7,8,9,1};
int odd[]= {2,4,6,8,1};
int even[] = {3,5,7,9};
Use % to get the remainder. If the remainder is nonzero, then the index is odd, otherwise even. But index starts from 0 and not 1, thus the first element's index is 0 and is even. if you want to sort according to that (seems to be you do), add 1 to index.
#include <stdio.h>
int main() {
int arr[] = {2, 3, 4, 5, 6, 7, 8, 9, 1}; // our array
const size_t max_size = sizeof(arr) / sizeof(arr[0]);
int odd[max_size];
size_t odd_cnt = 0;
int even[max_size];
size_t even_cnt = 0;
for (size_t i = 0; i != max_size; ++i) {
if ((i + 1) % 2) { // if (i + 1) % 2 is nonzero, i + 1 is odd
odd[odd_cnt++] = arr[i];
} else {
even[even_cnt++] = arr[i];
}
}
for (size_t i = 0; i != odd_cnt; ++i) {
printf("%d ", odd[i]);
}
printf("\n");
for (size_t i = 0; i != even_cnt; ++i) {
printf("%d ", even[i]);
}
printf("\n");
return 0;
}
I should make new array out of existing one (ex. 1 0 4 5 4 3 1) so that the new one contains digits already in existing array and the number of their appearances.
So, the new one would look like this: 1 2 0 1 4 2 5 1 3 1 (1 appears 2 times, 0 appears 1 time.... 3 appears 1 time; the order in which they appear in first array should be kept in new one also); I know how to count no. of times a value appears in an array, but how do I insert the no.of appearances? (C language)
#include <stdio.h>
#define max 100
int main() {
int b, n, s, i, a[max], j, k;
printf("Enter the number of array elements:\n");
scanf("%d", &n);
if ((n > max) || (n <= 0)) exit();
printf("Enter the array:\n");
for (i = 0; i < n; i++)
scanf("%d", a[i]);
for (i = 0; i < n; i++) {
for (j = i + 1; j < n;) {
if (a[j] == a[i]) {
for (k = j; k < n; k++) {
a[k] = a[k + 1];
}}}}
//in the last 5 rows i've tried to compare elements, and if they are same, to increment the counter, and I've stopped here since I realised I don't know how to do that for every digit/integer that appears in array//
If you know that the existing array consists of digits between 0 and 9, then you can use the index of the array to indicate the value that you are incrementing.
int in[12] = {1,5,2,5,6,5,3,2,1,5,6,3};
int out[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 12; ++i)
{
++out[ in[i] ];
}
If you provide any code snippet, its easy for the community to help you.
Try this, even you optimize the no.of loops :)
#include <stdio.h>
void func(int in[], int in_length, int *out[], int *out_length) {
int temp[10] = {0}, i = 0, j = 0, value;
//scan the input
for(i=0; i< in_length; ++i) {
value = in[i];
if(value >= 0 && value <= 9) { //hope all the values are single digits
temp[value]++;
}
}
// Find no.of unique digits
int unique_digits = 0;
for(i = 0; i < 10; ++i) {
if(temp[i] > 0)
unique_digits++;
}
// Allocate memory for output
*out_length = 2 * unique_digits ;
printf("digits: %d out_length: %d \n",unique_digits, *out_length );
*out = malloc(2 * unique_digits * sizeof(int));
//Fill the output
for(i = 0, j = 0; i<in_length && j < *out_length; ++i) {
//printf("\n i:%d, j:%d val:%d cout:%d ", i, j, in[i], temp[in[i]] );
if(temp[in[i]] > 0 ) {
(*out)[j] = in[i];
(*out)[j+1] = temp[in[i]];
temp[in[i]] = 0; //Reset the occurrences of this digit, as we already pushed this digit into output
j += 2;
}
}
}
int main(void) {
int input[100] = {1, 0, 4, 5, 4, 3, 1};
int *output = NULL, output_length = 0, i = 0;
func(input, 7, &output, &output_length );
for(i=0; i < output_length; i+=2) {
printf("\n %d : %d ", output[i], output[i+1]);
}
return 0;
}
I'm trying to randomize 4 different numbers in C and trying the next code:
{
int num1 = 0, num2 = 0, num3 = 0, num4 = 0;
int i = 0;
while (num1 == num2 && num1 == num3 && num1 == num4 && num2 == num3 && num2 == num4 && num3 == num4 && num3 == num2)
{
num1 = rand() % 7;
num2 = rand() % 7;
num3 = rand() % 7;
num4 = rand() % 7;
}
printf("%d %d %d %d\n", num1, num2, num3, num4);
}
The code suppose to check if the numbers are not equal and if they are equal, it needs to generate new numbers until they are all distinct.
But for some reason, it's not working well and even right numbers it puts them as wrong and it becomes and endless loop.
What am I missing?
This code will pick 4 different numbers in the range 0 .. 6, it works by creating an array of available numbers, as each is picked it is removed from the list.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define RANGE 7 // how many different numbers
#define PICK 4 // how many to pick
int main(void) {
int pool[RANGE];
int size, n, i;
for (size=0; size<RANGE; size++) {
pool[size] = size; // create number pool 0..6
}
srand((unsigned)time(NULL));
// pick different numbers
for(i=0; i<PICK; i++) {
n = rand() % size; // random array index
printf("%d ", pool[n]); // select number from pool
pool[n] = pool[--size]; // remove from pool
}
printf("\n");
return 0;
}
Try like this
void
get_random_values(int *values)
{
int source[] = {0, 1, 2, 3, 4, 5, 6};
for (int i = 0 ; i < 7 ; ++i)
{
int saved;
int j = rand() % 7;
int k = rand() % 7;
saved = source[j];
source[j] = source[k];
source[k] = saved;
}
values[0] = source[0];
values[1] = source[1];
values[2] = source[2];
values[3] = source[3];
}
int
main(void)
{
int values[4];
srand(time(NULL));
get_random_values(values);
for (int i = 0 ; i < 4 ; ++i)
fprintf(stderr, "%d ", values[i]);
fprintf(stderr, "\n");
return 0;
}
Don't forget to set the random seed srand() at the program startup or you will get the same sequence always.
To get a random, unbiased sequence:
#include <stdio.h>
#include <stdlib.h>
#define N 7
int main(int argc, char **argv)
{
// seed random number generator with first argument for easier testing
if (argc > 1) {
srand(atoi(argv[1]));
}
int array[N] = {0,1,2,3,4,5,6};
// Fisher–Yates shuffle:
// https://en.wikipedia.org/w/index.php?oldid=697311634#The_modern_algorithm
for (unsigned i = 0; i < N - 1; ++i) {
unsigned modulo = N - i;
// unbiased rand() % modulo:
// https://stackoverflow.com/a/10989061/416224
unsigned j;
do {
j = rand();
} while (j >= RAND_MAX - (RAND_MAX % modulo));
j %= modulo;
if (j > 0) {
int tmp = array[i];
array[i] = array[i + j];
array[i + j] = tmp;
}
}
for (unsigned i = 0; i < N; ++i) {
printf("%u. %d\n", i + 1, array[i]);
}
return 0;
}
Please follow the referenced links in the code.
I would suggest universal solution:
array of any size
lower and upper bounds sent as parameters.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void random(int* values, int amount, int lower_bound, int upper_bound)
{
int i=0, j=0, temp;
if(amount > upper_bound - lower_bound + 1)
return; // if there are more numbers than given bound
for(i=0; i<amount; )
{
temp = rand() % ( upper_bound - lower_bound + 1 ) + lower_bound;
for(j=i-1; j>=0; --j)
if(temp==values[j])
break;
if(temp==values[j])
continue;
values[i]=temp;
++i;
}
}
int main()
{
srand(time(NULL));
int arr[4]={0,0,0,0};
random(arr, 4, 5, 10);
for(int i=0; i<4; ++i)
printf("%d\n", arr[i]);
}
With this you can have (for example) 10 numbers of original values from -6 to 7.
int i,j,vec[15]={0};
srand (time(NULL));
for (i=0;i<15;i++){
vec[i]=rand() % 25+1;
for (j=0;j<15;j++){
if (i!=j){
while(vec[i]==vec[j]){
vec[i]=rand() % 25+1;
}
}
}
printf("%d\n",vec[i]);
}
return 0;
}
the code still gives me repeated numbers
EXAMPLE:
24
3
7
20
18
10
12
17
9
7
4
25
13
15
21
I cant figure out what to do with it
You have your loops mixed up. The logic is: Generate a random number until you have found one that isn't in the list.
The way you do it, you generate a new number inside the checking loop. But that doesn't work. Say you're generating the 4th number and find it is equal to the third. Then you generate a new one which might well be equal to any you have already checked against.
You also check uninitialised elements when j > i. Your inner loop should only run up to i.
So:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main()
{
int vec[15] = { 0 };
int i, j;
srand(time(NULL));
for (i = 0; i < 15; i++) {
int okay = 0;
while (!okay) {
vec[i] = rand() % 25 + 1;
okay = 1;
for (j = 0; j < i; j++) {
if (vec[i] == vec[j]) okay = 0;
}
}
printf("%d\n", vec[i]);
}
return 0;
}
That still looks a bit awkward with that okay variable. In my opinion, checking for duplicates should be a separate function:
int contains(int arr[], int n, int x)
{
while (n--) {
if (arr[n] == x) return 1;
}
return 0;
}
int main()
{
// snip ...
for (i = 0; i < 15; i++) {
do {
vec[i] = rand() % 25 + 1;
} while (contains(vec, i, vec[i]));
printf("%d\n", vec[i]);
}
// snip ...
}
In your case the range of possible numbers isn't mich bigger than the number of array elements. You could also create an ordered array {1, 2, 3, ..., 25}, then shuffle it and use only the first 15 elements.
Reset j in the while loop:
for (j=0;j<i;j++){ //Use j<i
if (i!=j){
while(vec[i]==vec[j]){
vec[i]=rand() % 25+1;
j=-1;//-1 because in the next iteration,j will start from 0
}
}
}
Are you actually trying to shuffle the numbers, rather than fill the array with randoms? (It looks like you want an array with numbers from 1 to 25, but in random order.) rand() can give you duplicate numbers (they're random, after all!)
Try this:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
int
main( int argc, char **argv )
{
int i, vec[25];
for (i = 0; i < 25; ++i) vec[i] = i + 1;
/* Shuffle entries */
srand( time( 0 ) );
for (i = 0; i < 1000; ++i) {
int a = rand( ) % 25;
int b = rand( ) % 25;
if (a != b) {
int tmp = vec[a];
vec[a] = vec[b];
vec[b] = tmp;
}
}
/* Print shuffled array */
for (i = 0; i < 25; ++i) printf( "%d: %d\n", i, vec[i] );
return 0;
}
#include<stdio.h>
#include<stdlib.h>
int inArray(int, int, int*);
int main()
{
int i,j,vec[15]={0};
int temp;
srand (time(NULL));
for (i=0;i<15;i++){
temp =rand() % 25+1;
while(inArray(i+1,temp, vec) == 1){
temp = rand() % 25+1;
}
vec[i] = temp;
printf("VECT[%d] \t= %d\n",i,vec[i]);
}
return 0;
}
int inArray(int count, int input, int* array){
int i = 0;
for(i=0; i<count; i++){
if(input == array[i]){
return 1;
}
}
return 0;
}
Gave an output:
VECT[0] = 24
VECT[1] = 19
VECT[2] = 1
VECT[3] = 25
VECT[4] = 22
VECT[5] = 18
VECT[6] = 7
VECT[7] = 8
VECT[8] = 12
VECT[9] = 21
VECT[10] = 11
VECT[11] = 6
VECT[12] = 23
VECT[13] = 20
VECT[14] = 15
The checking was off, you would change and not break allowing it to be changed to a previous value.
You can use an array
int randNumbers[25]; // fill it starting 0 to 25 then
randomize the number in a range between 0 and 25 after swap the number in the randomized index with the last number in your array
randomize 0 to 23
and so on....
int main(int argc, char **argv) {
static const int size = 25;
int numbers[size];
for( int i = 0; i < size; i++ ){
numbers[i] = i;
}
srand (time(NULL));
for( int i = 0; i < size; i++ ){
int rIndex = rand()%(size - i);
int rNum = numbers[rIndex];
numbers[rIndex] = numbers[size-i];
printf("%d ", rNum);
}
return 0;
}
O(n) complexity...