Hello I'm writing a program that would generate 10 random characters in order to form a word (it's for a game).
so here's my function:
void GenerateTen(int number)
{
int i;
char abc[30]="abcdefghijklmnopqrstuvwxyz";
char newabc[8];
for (i = 0; i < number; ++i) {
newabc[i] = abc[rand() % (sizeof(abc) - 1)];
printf("%c ", newabc[i]);
}
newabc[number] = 0;
}
the number variable contains 10 and the output is supposed to simply print these 10 characters in the array. There's no error by the compiler however, the program generates the same set of characters. Thank you for your help! :-)
I got your problem. You have to seed it. Seeding it with the time is a good idea: srand()
rand() returns pseudo-random numbers. It generates numbers based on a given algorithm. The starting point of that algorithm is always the same, so you'll see the same sequence generated for each invocation.
You can set the "seed" of the random generator with the srand function(only call srand once in a program). One common way to get different sequences from the rand() generator is to set the seed to the current time or the id of the process:
srand(time(NULL)); or srand(getpid()); at the start of the program.
Reference: https://stackoverflow.com/a/1108810/5352399
You can update your code as follows.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(NULL));
for(int i = 0; i < 5; i++){
GenerateTen(8);
}
return 0;
}
void GenerateTen(int number) {
int i;
char abc[26]="abcdefghijklmnopqrstuvwxyz";
char newabc[8];
for (i = 0; i < number; ++i) {
newabc[i] = abc[rand() % (sizeof(abc) - 1)];
printf("%c ", newabc[i]);
}
newabc[number] = 0;
}
It outputs:
r x r a f d a b
f f t i x m l b
r k j e p h d v
s w a c p g v h
e n j l r j n w
You need to initialize the pseudo-random number generator using srand().
Just add this after your main().
srand(time(NULL));
What srand(time(NULL)) actually does is srand() generates pseudo-random numbers using a seed value, and time(NULL) returns the current calendar time.
So theoretically, your srand() function is guaranteed to get a different seed value on every runtime. Hence the values produced by rand() would be different each time.
Apart from calling srand(), you should be very careful that you're actually allocating an array of 8 elements (char newabc[8]) and indexing it up to number, so you should expect a buffer overflow when number >= 8). As you're not returning it you can remove it. If you plan on returning it you should allocate it beforehand: char* newabc = (char*)calloc(number+1, sizeof(char));
You can also remove the char abc[30] by realizing that abc[rand() % (sizeof(abc) - 1)] actually is 'a' + rand() % 26. Unless you want to use a custom dictionary with a subset of letter, in which case it would be better to keep it in global memory (outside of the function, or as static inside the function if you prefer to restrain its scope). And mind that sizeof(abc)might not be the same as strlen(abc) depending on your architecture.
So all in all you could end up with:
char* generate_random(int number) // Better C-style name
{
int i;
char* newabc = (char*)calloc(number, sizeof(char));
if (newabc == NULL)
return NULL;
for (i = 0; i < number; ++i) {
newabc[i] = 'a' + (rand() % 26);
// printf("%c ", newabc[i]); // Not needed anymore, except for debugging
}
// newabc[number] = 0; // Not needed because we used 'calloc()' which zeroes the allocated memory
return newabc;
}
Related
Program not working, not giving output, I don't know what to do, where the problem is.
I'm trying to find out the largest palindrome made from the product of two 3-digit numbers.
#include <stdio.h>
main() {
int i, k, j, x;
long int a[1000000], palindrome[1000000], great, sum = 0;
// for multiples of two 3 digit numbers
for (k = 0, i = 100; i < 1000; i++) {
for (j = 100; j < 1000; j++) {
a[k] = i * j; // multiples output
k++;
}
}
for (i = 0, x = 0; i < 1000000; i++) {
// for reverse considered as sum
for (; a[i] != 0;) {
sum = sum * 10 + a[i] % 10;
}
// for numbers which are palindromes
if (sum == a[i]) {
palindrome[x] = a[i];
x++;
break;
}
}
// comparison of palindrome number for which one is greatest
great = palindrome[0];
for (k = 0; k < 1000000; k++) {
if (great < palindrome[k]) {
great = palindrome[k];
}
}
printf("\ngreatest palindrome of 3 digit multiple is : ", great);
}
What do you mean with "not working"?
There are two things, from my point of view:
1) long int a[1000000], palindrome[1000000]
Depending on you compile configuration you could have problems compiling your code.
Probably the array is too big to fit in your program's stack address space.
In C or C++ local objects are usually allocated on the stack. Don't allocate it local on stack, use some other place instead. This can be achieved by either making the object global or allocating it on the global heap.
#include <stdio.h>
long int a[1000000], palindrome[1000000], great, sum = 0;
main() {
int i, k, j, x;
2) printf("\ngreatest palindrome of 3 digit multiple is : ", great);
I will change it by :
printf("\ngreatest palindrome of 3 digit multiple is %li: ", great);
Regards.
Compiling and running your code on an on-line compiler I got this:
prog.c:3:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main() {
^
prog.c:34:61: warning: data argument not used by format string [-Wformat-extra-args]
printf("\ngreatest palindrome of 3 digit multiple is : ", great);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
2 warnings generated.
Killed
Both the warnings should be taken into account, but I'd like to point out the last line. The program was taking too much time to run, so the process was killed.
It's a strong suggestion to change the algorithm, or at least to fix the part that checks if a number is a palindrome:
for (; a[i] != 0;) { // <-- If a[i] is not 0, this will never end
sum = sum * 10 + a[i] % 10;
}
I'd use a function like this one
bool is_palindrome(long x)
{
long rev = 0;
for (long i = x; i; i /= 10)
{
rev *= 10;
rev += i % 10;
}
return x == rev;
}
Also, we don't need any array, we could just calculate all the possible products between two 3-digits number using two nested for loops and check if those are palindromes.
Starting from the highest numbers, we can store the product, but only if it's a palindrome and is bigger than any previously one found, and stop the iteration of the inner loop as soon as the candidate become less then the stored maximum. This would save us a lot of iterations.
Implementing this algorithm, I found out a maximum value of 906609.
I'm trying to generate a random 10-digit code, but even though I use the absolute value of every number in the code, it still sometimes prints a negative value
#include <stdio.h>
int main()
{
int i;
int r;
int barcode[11];
srand(time(NULL));
for(i=0;i <= 10;i++){
r = rand() % 10;
barcode[i] = abs(r);
}
printf("%d",barcode);
return 0;
}
Because you are actually printing the address of an integer array, not a string.
This line:
printf("%d",barcode);
Basically prints the address of barcode as a signed integer instead of the contents of barcode.
You of course could do this:
printf("%d%d%d%d%d%d%d%d%d%d",barcode[0], barcode[1], barcode[2], barcode[3], barcode[4], barcode[5], barcode[6], barcode[7], barcode[8], barcode[9]);
But perhaps a better way is to generate a string of characters instead of an array of integers. Quick mod to your code is to add to '0' to each random value in each interation of the loop and append to a char array.
int main()
{
int i;
int r;
char barcode[11]; // array of chars instead of ints
srand(time(NULL));
for(i=0; i < 10; i++) // loop 10 times, not 11
{
r = rand() % 10;
barcode[i] = '0' + r; // convert the value of r to a printable char
}
barcode[10] = '\0'; // null terminate your string
printf("%s\n",barcode);
return 0;
}
The above will generate a 10 digit code, with a small possibility of the first number being a leading zero. If that's not what you want, that's a simple bug fix. (Which I'll leave up to you...)
So I'm just learning C and I would like to know how you could prevent a variable randomized with the rand() function from repeating the same number. I have a script which simply randomizes and prints a variable in a for loop 4 times. How could I make it so the variable never gets the same number after each time it uses the rand() function?
#include <stdio.h>
#include <stdlib.h>
int randomInt;
int main()
{
srand(time(0));
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4;
printf("%d\n", randomInt);
}
return 0;
}
On most machines, int is 32 bits. So after 232 iterations, you are sure that you'll get some repetition (and probably much before).
If you restrict yourself to much less loops, consider e.g. keeping an array of previously met random numbers (or some hash table, or some binary tree, or some other container).
For a loop repeated only 4 times, keeping an array of (at most 4-1) previously emitted numbers is quite simple, and efficient enough.
Read also about the pigeonhole principle.
A slightly different approach.
int set[] = {0, 1, 2, 3 } ;
srand(time(0));
shuffle(set,4);
using the shuffle algorithm given in this question
https://stackoverflow.com/a/6127606/9288531
I'm guessing that you are getting the same numbers because your are running your program multiple times within the same second. If time(0) hasn't changed, you will have the same seed and the same random numbers generated. Unless your program runs extremely quickly, I imagine using a seed based on microseconds instead of seconds would work:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
int randomInt;
int main()
{
struct timeval my_microtimer;
gettimeofday(&t1, NULL);
srand(t1.tv_sec * my_microtimer.tv_usec);
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4;
printf("%d\n", randomInt);
}
return 0;
}
What you could do is keeping track of each number you already generated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int hasMyNumberAlreadyBeenGenerated(int number, int generatedNumbers[], int size){
for(int i = 0; i < size + 1; i++){
//If you already generated the number, it should be present somewhere in your array
if(generatedNumbers[i] == number) return 1;
//If you did not, find the first available space in your array, and put the number you generated into that space
if(generatedNumbers[i] == 0){
generatedNumbers[i] = number;
break; //No need to continue to check the array
}
}
return 0;
}
int main()
{
int randomInt;
int generatedNumbers[4];
//We set "0" in all the array, to be sure that the array doesn't contain unknown datas when we create it
memset(generatedNumbers, 0x0, sizeof(generatedNumbers));
srand(time(0));
for (int i = 0; i < 4; ++i) {
randomInt = rand() % 4 + 1;
//As long as the number you generate has already been generated, generate a new one
while(hasMyNumberAlreadyBeenGenerated(randomInt, generatedNumbers, i) == 1){
randomInt = rand() % 4 + 1;
}
printf("generated : %d\n", randomInt);
}
return 0;
}
The problem with this method is that you can't generate a 0, because if you do you'll endlessly loop.
You can bypass this problem using a dynamic array using malloc() function.
If you want to write clean code you should define how many numbers you want to generate with a #define.
What you seem to be asking is a non-random set of numbers 0 to 3 in a random order. Given that;
int set[] = {0, 1, 2, 3 } ;
int remaining = sizeof(set) / sizeof(*set) ;
while( remaining != 0 )
{
int index = rand() % sizeof(set) / sizeof(*set) ;
if( set[index] > 0 )
{
printf( "%d\n", set[index] ) ;
set[index] = -1 ;
remaining-- ;
}
}
For very large sets, this approach may not be practical - the number of iterations necessary to exhaust the set is non-deterministic.
Hi I want to know is there a way to store randnumber without prompting user for input. In this example we want user to store 16 randnumbers in array storerand without prompting the user for randnums for example:
#include<stdio.h>
#include<stdlib.h>
void main() {
int randnum;
int i=0;
int storerand[16]; // storing randnumbers
randnum=rand();
while(i <16){
storerand[i]=randnum; // why is this not storing 16 rand number how can i store 16 randnumbers
i++;
}
return 0;
An easy way to generate random numbers in C is to use the rand() function which comes with <stdlib.h>. Note that if you do not seed with the time library, you will receive the same random numbers every time you run your program.
#include <stdlib.h>
#include <time.h>
int main (void) {
//Uses system time to seed a proper random number.
srand(time(NULL));
//rand() generates a random integer
int a = rand();
//Use mod to restrict range:
int b = rand()%5; //random integer from 0-4
return 0;
}
You also need to make sure to increment your index i within your while loop.
while(i < 16) {
storerand[i] = rand();
i++;
}
You initialise randnum with a random value here:
randnum=rand();
And then you run your loop to put its value into each slot of your array. That means you're putting the same value into each slot.
while(i <16){
storerand[i]=randnum;
i++;
}
The solution is to call rand() each time around the loop:
for( i = 0; i < 16; i++ ) {
storerand[i] = rand();
}
Hello friends I need your help.
My program is such an array size 1000 where the numbers should be between 0-999. These numbers should be determined randomly (rand loop) and the number must not be repeated. Would be considered the main part, I have to count how many times I used rand().
My idea is that: one loop where it initializes all the 1000 numbers, and if in this loop they check whether the number appears twice, if the number appears twice is set it again until that not appear twice (maybe this is not the best way but ...)
It is my exercise (Here I need your help)-
#include <stdio.h>
#include <stdlib.h>
int main()
{
int const arr_size = 1000;
int i, j, c;
int arr[arr_size];
int loop = 0;
for(i = 0; i<arr_size; i++)
{
arr[i] = rand() % 1000;
loop++;
if (arr[i] == arr[i - 1])
{
arr[i] = rand() % 1000;
loop++;
}
}
printf("%d\n",loop);
}
So if anyone can give me advice on how I can make it work I appreciate your help.
Thanks.
As suggested, shuffling the set will work but other indirect statistical quantities might be of interest, such as the distribution of the loop variable as a function of the array index.
This seemed interesting so I went ahead and plotted the distribution of the loop as a function of the array index, which generally increases as i increases. Indeed, as we get near the end of the array, the chance of getting a new random number that is not already in the set decreases (and hence, the value of the loop variable increases; see the code below).
Specifically, for an array size = 1000, I recorded the non-zero values generated for loop (there were around 500 duplicates) and then made a plot vs the index.
The plot looks like this:
The code below will produce an array with the unique random values, and then calculate the value for loop. The loop values could be stored in another array and then saved for later analysis, but I didn't include that in the code below.
Again, I'm not exactly sure this fits the application, but it does return information that would not necessarily be available from an approach using a shuffle algorithm.
NOTE: some folks expressed concerns about how long this might take but it runs pretty quick, on my 2011 Macbook Pro it took a about a second for an array size of 1000. I didn't do a big-O analysis as a function of the array size, but that would be interesting too.
NOTE 2: its more elegant to use recursion for the numberInSet() function but it seemed best to keep simple.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h> /* If C99 */
const int ARR_SIZE = 1000;
/* Check if the number is in the set up to the given position: */
bool numberInSet(int number, int* theSet, int position);
int main()
{
int* arr = malloc(sizeof(int)*ARR_SIZE);
srand((unsigned int)time(NULL));
/* Intialize array with rand entries, possibly duplicates: */
for(int i = 0; i < ARR_SIZE; i++)
arr[i] = rand() % ARR_SIZE;
/* Scan the array, look for duplicate values, replace if needed: */
for(int i = 0; i < ARR_SIZE; i++) {
int loop = 0;
while ( numberInSet(arr[i], arr, i-1) ) {
arr[i] = rand() % ARR_SIZE;
loop++;
}
/* could save the loop values here, e.g., loopVals[i] = loop; */
}
for(int i = 0; i < ARR_SIZE; i++)
printf("i = %d, %d\n",i,arr[i]);
/* Free the heap memory */
free(arr);
}
bool numberInSet(int number, int* theSet, int position) {
if (position < 0)
return false;
for(int i = 0; i <= position; i++)
if (number == theSet[i])
return true;
return false;
}
To make sure all random number you get in the same program are different, you must seed once the random generator:
srand (time(NULL)); //seed the random generator
//in the loop, rand will use the seeded value
rand() % 1000