how can i make two equal random numbers in c - c

I'm new to coding and i need help with my project: so, what i need to do is code a "finding the two same cards game", in which every card has a number and we're basically trying to find that two equal numbers. those numbers should be generated with rand() function but i cannot think a way to how to make two random numbers equal to each other if I'm using the rand() function. i don't know if i worded this the best way but i hope you get what i mean and if you don't I'm open to explain it with an example.
thanx in advance!

Just create half as many elements and duplicate them. You can actually take consecutive numbers and shuffle them. This way you make sure every number is repeated exactly once:
int main()
{
enum { size = 10 };
int cards[size];
for (int i = 0; i != size / 2; ++i)
{
cards[i] = i;
cards[size/2 + i] = i;
}
// now shuffle the array
}

Related

Cycling through interval in C efficiently

I have dynamically allocated array consisting of a lot of numbers (200 000+) and I have to find out, if (and how many) these numbers are contained in given interval. There can be duplicates and all the numbers are in random order.
Example of numbers I get at the beginning:
{1,2,3,1484984,48941651,489416,1816,168189161,6484,8169181,9681916,121,231,684979,795641,231484891,...}
Given interval:
<2;150000>
I created a simple algorithm with 2 for loops cycling through all numbers:
for( int j = 0; j <= numberOfRepeats; j++){
for( int i = 0; i < arraySize; i++){
if(currentNumber == array[i]){
counter++;
}
}
currentNumber++;
}
printf(" -> %d\n", counter);
}
This algorithm is too slow for my task. Is there more efficient way for me to implement my solution? Could sorting the arrays by value help in this case / wouldn't that be too slow?
Example of working program:
{ 1, 7, 22, 4, 7, 5, 11, 9, 1 }
<4;7>
-> 4
The problem was simple as the single comment in my question answered it - there was no reason for second loop. Single loop could do it alone.
My changed code:
for(int i = 0; i <= arraySize-1; i++){
if(array[i] <= endOfInterval && array[i] >= startOfInterval){
counter++;
}
This algorithm is too slow for my task. Is there more efficient way for me to implement my solution? Could sorting the arrays by value help in this case / wouldn't that be too slow?
Of course, it is slow. A single pass algorithm to count the number of elements that are in the set should suffice, just count them in a single pass if they pass the test (be n[i] >= lower bound && be n[i] < upper bound or similar approach) will do the work.
Only in case you need to consider duplicates (e.g. not counting them) you will need to consider if you have already touched them or no. In that case, the sorting solution will be faster (a qsort(3) call is O(nlog(n)) against the O(nn) your double loop is doing, so it will run in an almost linear, then you make a second pass over the data (converting your complexity to O(nlog(n) + n), still lower than O(nn) for the large amount of data you have.
Sorting has the advantage that puts all the repeated key values together, so you have to consider only if the last element you read was the same as the one you are processing now, if it is different, then count it only if it is in the specified range.
One final note: Reading a set of 200,000 integers into an array to filter them, based on some criteria is normally a bad, non-scalable way to solve a problem. Your problem (select the elements that belong to a given interval) allow you for a scalable and better solution by streaming the problem (you read a number, check if it is in the interval, then output it, or count it, or whatever you like to do on it), without using a large amount of memory to hold them all before starting. That is far better way to solve a problem, as it allows you to read a true unbounded set of numbers (coming e.g. from a file) and producing an output based on that:
#include <stdio.h>
#define A (2)
#define B (150000)
int main()
{
int the_number;
size_t count = 0;
int res;
while ((res = scanf("%d", &the_number)) > 0) {
if (the_number >= A && the_number <= B)
count++;
}
printf("%zd numbers fitted in the range\n", count);
}
on this example you can give the program 1.0E26 numbers (assuming that you have an input file system large enough to hold a file this size) and your program will be able to handle it (you cannot create an array with capacity to hold 10^26 values)

How to randomize a place in array

I'm trying to code the game Minesweeper and for that I need to randomize the bombs locations.
Can someone help change the function a bit so that placing of bombs is randomized?
THE CODE:
void Createbomb(int*** bord, int size)//size+1
{
//bomb num.1
(*bord)[size - 5][size - 1] = 9;
//bomb num.2
(*bord)[size - 4][size - 4] = 9;
//bomb num.3
(*bord)[size - 3][size - 2] = 9;
//bomb num.4
(*bord)[size - 2][size - 2] = 9;
//bomb num.5
(*bord)[size - 1][size - 5] = 9;
}
I wrote a ncurses based Minesweeper a long time ago (around 1993). It's opensource and it's now in Github, If you want hints about how to implement some part of it, you have full source code there. You are free to download, clone, and even to show me better ways to implement something if you get some.
My approach was to use a matrix for the field cells, and to store on them the number of neighbour bombs, while one bit stored the presence of a bomb. I'm afraid it was written so long ago that I have not had a time to translate all the comments and identifiers into english... but probably this is a good time to do so.... let's think on it.
Do not use the modulus to get a pseudo-random number, since with a few trials, we can easily figure out which is going to be the next number. There are several ways of randomize in a good way, this is one way, that is better that using the modulus:
(If you have interest, there are more complex ways to generate random numbers)
#include <stdlib.h>
int random_num(int inf, int sup)
{
if(inf < 0 || sup-inf < 0) return -1; /*Only positive numbers because it is an array */
return inf+(int)(((sup-inf+1.0)*rand())/(RAND_MAX + 1.0));
}
RAND_MAX is a constant value defined in stdlib.h, roughly speaking it is a huge integer constant, i.e, a big integer number.
So, in your program you just have to call:
int x = random_num(0, size); /*Gets a new random number in the desired range*/
Suppose that the number of bombs you need is 5. Also, let initially board contain default value of 1 for all cells, and 9 only if there is a bomb present in the cell. Then you can do something like:
void createBomb(int*** board, int size){
srand(time(0));
int numOfBombsPlaced = 0;
while(numOfBombsPlaced < 5){
int x = rand()%size;
int y = rand()%size;
if ((*board)[x][y]==9):
continue;
numOfBombsPlaced++;
(*board)[x][y] = 9;
}
}
Note that the numbers generated by rand are not truly random, and depend on the initial seed. The seed is provided by srand. Using time for seed is a good option to randomise.

Generate random numbers without repeats

I want to generate random numbers without repeats till all gone, then again generating random numbers with the initial dataset.
I know keeping already generated numbers in an array and loopin through them to check whether it is alredy generated or the method deducting the numbers that are generated from the array and randomize numbers with the new array.
What I want is not those methods, if there is a way that is efficient using data structures will be quite nice, if it is any other method also ok
Thanks
Say you want to generate 1,000 unique random numbers and present them to some code one at a time. When you exhaust those numbers, you want to present the same numbers again, but in a different sequence.
To generate the numbers, use a hash table. In C#, it would look like this:
const int MaxNumbers = 1000;
HashSet<int> uniqueNumbers = new HashSet<int>();
Random rnd = new Random();
// generate random numbers until there are 1000 in the hash table
while (uniqueNumbers.Count < MaxNumbers)
{
uniqueNumbers.Add(rnd.Next());
}
// At this point you have 1,000 unique random numbers
// Put them in an array
int[] myNumbers = uniqueNumbers.ToArray();
This works because the HashSet.Add method rejects duplicates. And it's very fast because lookup in the hash table is O(1).
Now, you can serve them by setting a current index at 0 and increment it every time a number is requested. Something like:
int ixCurrent = 0;
int GetNextNumber()
{
if (ixCurrent < MaxNumbers)
{
++ixCurrent;
return myNumbers[ixCurrent-1];
}
But what to do when ixCurrent runs off the end of the array? Enter the Fisher-Yates Shuffle:
// out of numbers. Shuffle the array and return the first one.
for (int i = MaxNumbers-1; i > 0; --i)
{
int j = rnd.Next(i+1);
int temp = myNumbers[i];
myNumbers[i] = myNumbers[j];
myNumbers[j] = temp;
}
ixCurrent = 1;
return myNumbers[0];
}
If you know that the numbers you want to return are within a particular range (that is, you want to return the numbers 0-999 in random order), then you just fill an array with the values 0-999 and shuffle it.
I'm not sure what language you are using, but here's some C++ code that does what you're looking for. Instead of it searching an array, it just does a direct check of a specific section of memory for a set flag and if it isn't set then the number chosen is new and printed.
The section I marked as handler is the code that is first executed when a unique number is found. Change the 10's and the 11 to different numbers if you want a larger set of random numbers but you might have to wait forever for the output.
int main(int argc, char *argv[]){
char randn[10];
char randnset[10];
int n;
int ct=0;
memset(randnset,'1',10);
memset(randn,0,10);
while (ct < 10){
srand(time(NULL));
n=rand() % 11;
if (!randn[n]){
printf("%d\n",n); // handler
randn[n]='1';
ct++;
}
}
return 0;
}
Every random generator function takes a seed value as a parameter and uses it in its internal algorithm to generate random numbers. If you want to generate the same sequence of numbers, you have to use the same seed value. As an example you can achieve this in Java like this:
int seed = 10;
Random r = new Random(seed);
for(int i=0; i<10; i++){
System.out.println(r.nextInt());
}
The output is something like this (of course it will have different results in your system):
-1157793070
1913984760
1107254586
1773446580
254270492
-1408064384
1048475594
1581279777
-778209333
1532292428
and it gives me the same results each time I execute it.

Create actual random data in arrays

I have been working on an assignment, where I have to create a given number of arrays and fill them up with random data. The approach I would like to follow is I want the arrays to be filled with data, only a percentage. The problem is that for every array, the random values are in the same position and not spread how I would like.
I have been creating the arrays in this way:
int **array = malloc(DOC * sizeof *array);
for (i = 0; i < DOC; i++)
{
array[i] = malloc(MAXWORDS * sizeof **array);
}
and filling them using :
srand((unsigned) time(&t));
and
for(i = 0; i < DOC; i++){
for(j = 0; j < MAXWORDS; j++){
array[i][rand() %percentage]=rand() %VALUE;
}
}
Where
int percentage = rand() %MAXWORDS/10;
MAXWORDS defines the lenght of the array
DOC the number of arrays
VALUE is the max random value
As you can see the random values are all behaving identically.
I know that this has to do with the way that srand depends on the time to generate the numbers, and the execution of the program is really fast, so the similar data are because of the "similar" time. So what I am asking is for either a different day to generate random values or some trick I could do to fill the arrays differently.
With "rand() % percentage" you are only picking elements within the first 10% of each array. Instead, you probably want something like this:
for (i = 0; i < DOC; ++i){
for (j = 0; j < MAXWORDS; ++j) {
if (rand() % 100 <= 10) {
array[i][j] = rand() % VALUE;
}
}
}
This gives each elements in the array roughly a 10% chance of being initialized, which should result (for large enough arrays) in about 10% of the elements being initialized.
If you want exactly 10% of the array to be initialized, you could instead do something like placing all indices (0...j) into an array, randomizing the array, and picking the first MAXWORDS/10 indices from the randomized array for initialization.
rand() and srand(), especially when used with %, they don't produce random numbers as uniformly distributed as you may think.
Check Mersenne twister algorithm as an alternative pseudorandom number generator.
I think the problem is with how you are choosing the second index: rand() % percentage will always fill towards the front of the arrays.
The standard random number generator in C (srand + rand) tends to be pretty bad at generating numbers that pass statistical tests for randomness. There are more sophisticated random number generators with better properties available as part of the GNU Scientific Library that you may find helpful.

Using arrays in C

I have a troubling homework assignment and would like pointers in the correct direction.
The task is to develop a C program that accomplishes the following:
In the main(), create an a 2D array named qqqqq that can hold 48 integers (6 rows, 8 columns)
Populate qqqqq with randomly generated integer values between 1 and 15.
Calculate the total for each row.
Calculate the total for each column.
Display the contents of the 2D array in tabular format with the row totals to the right of the rows and the column totals at the bottom of the columns.
Where to start after main?
Here is what I have so far:
int main (void)
{
int qqqqq [6] [8];
int r;
int c;
srandom ((unsiged) time (NULL));
for (r=0; r <=6; r++)
{
for(c=0; c <=8; c++)
{
qqqqq[r][c] = random ( )
What do I do next?
I appreciate any help or guidance.
Thanks
-James
Algorithmic Thinking
Here is how I would tackle this problem:
Write the algorithm in my own words.
Find out how to generate random numbers in the C language.
Learn how to print information on the screen.
Algorithm
The algorithm is the set of steps you need to solve the problem. The task at hand already describes the problem, but it is often good practice to re-write it in your own words. (As a practical point, you can then take your words to your client -- in this case, your teacher -- and confirm that your understanding of the problem is correct.)
Create a 2D array
Populate the array with random numbers.
Calculate the sum of each row of numbers (need a row sum counter).
Calculate the sum of each column of numbers (need a column sum counter).
Print the 2D array to the screen.
Print the sum of each row at the end of each row.
Print the sum of each column at the end of each column.
Assumption: Neither sum of sums are printed. (For example, the sum of the column sum.)
Generate Random Numbers
Google is helpful here. Try a Google search for:
generate random integers C
You will find lots of help, especially tips about the rand() function. Modify the Google search:
generate random integers C rand()
This search finds a great resource: http://www.cplusplus.com/reference/clibrary/cstdlib/rand/
Print Information
Again, a Google search can help here:
print information on the screen in C
This yields: http://www.daniweb.com/software-development/c/threads/9688
The printf function seems handy. Find out more about it:
printf C
This yields a familiar site: http://www.cplusplus.com/reference/clibrary/cstdio/printf/
Development
If you really want to "wow" your professor:
Identify the parts of your program that are most likely to change and make them constants.
Separate your program into logical areas (called functions).
Use meaningful variable names. Yes r and c likely represent rows and columns, but for the amount of time it takes to spell out row and column, it will save anyone reading your code from having to either make a guess or read the code to discover its true use.
Tell your professor that qqqqq could use a better name. Suggest one, even.
For example:
#include <stdio.h>
/* Subject to change; only change it in one spot. */
#define MAX_ROWS 6
#define MAX_COLS 8
#define MIN_RANDOM_NUMBER 1
#define MAX_RANDOM_NUMBER 15
/** Returns a number between MIN_RANDOM_NUMBER and MAX_RANDOM_NUMBER. */
int randomNumber() {
return 0; /* FIX ME to use rand() and the modulus operator. */
}
int main( int argc, char *argv[] ) {
int qqqqq[MAX_ROWS][MAX_COLS];
/* FIX ME: Move these variables into the display function. */
int sumRows = 0;
int sumCols = 0;
/* Use different random numbers each time the program runs. */
seedRandomNumber();
/* Initialize the array with random numbers. */
for( int row = 0; row < MAX_ROWS; row++ ) {
for( int col = 0; col < MAX_COLS; col++ ) {
qqqqq[row][col] = randomNumber();
}
}
/* Display the array to the screen along with the sum totals. */
display( qqqqq );
}
Note that you have a choice to make.
You could pass the sumRows variable into the display function, or you could code the display function to call calculateSumRows itself. My preference is to always simplify the function prototypes. That is, reduce the number of parameters. It makes things easier to change in the future.
So write display as something like:
void display( int randomValues[MAX_ROWS][MAX_COLS] ) {
int sumCols = 0;
for( int row = 0; row < MAX_ROWS; row++ ) {
/* FIX ME: Write the calculateSumCols function. */
sumCols = calculateSumCols( randomValues, row );
for( int col = 0; col < MAX_COLS; col++ ) {
/* FIX ME: Use printf here to display the value at this row/column. */
}
}
/* FIX ME: Use printf here to display sumRows. */
for( int col = 0; col < MAX_COLS; col++ ) {
/* FIX ME: Use printf here to display the value of the rows. */
printf( "%d ", calculateSumRows( randomValues, col ) );
}
}
That should get you started.
Note that there are a number of simplifications and optimizations you could make here. Forget them. Get the code so that it actually works first. Once the code works, save it. Make a back up copy, even.
Then start to change it. See if you can remove variables. Perhaps you can even remove some of the for loops. If you make a mistake, you can always reference your back up copy. Eventually your "back up" copy will become a "source code repository".
That's a pretty good start! Note, though, that the valid indices for an arrayof dimension X are 0...(X-1). Your loops should look like
for (r=0; r <6; r++)
(Note that "<6" rather than "<=6".
Now you need another array to hold the row totals, and an array to hold the column totals, and then some more loops to calculate those and store them in the arrays.
Some key things:
What does random() return?
What is the total of a row/column?
This is just adding up all the
numbers in the row/column. Try
writing a function to add up all the
values in one given row or column.
Think of how to print out a row
of a matrix. Then do this for every
row in the matrix.
There are 6 rows and 8 columns, and you need a total for each of those. Start by making some more arrays as places to store those totals.

Resources