How to randomize a place in array - c

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.

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 can i make two equal random numbers in 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
}

Specific permutations of 32 card deck (in C)

I want to generate all permutations of 32 card deck, I represent cards as numbers 0-7, so I don´t care about color of the card. The game is very simple (divide deck into two gropus, compare two cards, add both cards to group of bigger card). I have already code this part of game, but deck is now generating randomly, and I want to look to all possibilities of cards, and make some statistics about it. How can I code this card generating? I totaly don´t know, how to code it.
Because I was just studying Aaron Williams 2009 paper "Loopless Generation of Multiset Permutations by Prefix Shifts", I'll contribute a version of his algorithm, which precisely solves this problem. I believe it to be faster than the standard C++ next_permutation which is usually cited for this problem, because it doesn't rely on searching the input vector for the pivot point. But more extensive benchmarking would be required to produce a definitive answer; it is quite possible that it ends up moving more data around.
Williams' implementation of the algorithm avoids data movement by storing the permutation in a linked list, which allows the "prefix shift" (rotate a prefix of the vector by one position) to be implemented by just modifying two next pointers. That makes the algorithm loopless.
My version here differs in a couple of ways.
First, it uses an ordinary array to store the values, which means that the shift does require a loop. On the other hand, it avoids having to implement a linked-list datatype, and many operations are faster on arrays.
Second, it uses suffix shifts rather than prefix shifts; in effect, it produces the reverse of each permutation (compared with Williams' implementation). I did that because it simplifies the description of the starting condition.
Finally, it just does one permutation step. One of the great things about Williams' algorithm is that the state of the permutation sequence can be encapsulated in a single index value (as well as the permutation itself, of course). This implementation returns the state to be provided to the next call. (Since the state variable will be 0 at the end, the return value doubles as a termination indicator.)
Here's the code:
/* Do a single permutation of v in reverse coolex order, using
* a modification of Aaron Williams' loopless shift prefix algorithm.
* v must have length n. It may have repeated elements; the permutations
* generated will be unique.
* For the first call, v must be sorted into non-descending order and the
* third parameter must be 1. For subsequent calls, the third parameter must
* be the return value of the previous call. When the return value is 0,
* all permutations have been generated.
*/
unsigned multipermute_step(int* v, unsigned n, unsigned state) {
int old_end = v[n - 1];
unsigned pivot = state < 2 || v[state - 2] > v[state] ? state - 1 : state - 2;
int new_end = v[pivot];
for (; pivot < n - 1; ++pivot) v[pivot] = v[pivot + 1];
v[pivot] = new_end;
return new_end < old_end ? n - 1 : state - 1;
}
In case that comment was unclear, you could use the following to produce all shuffles of a deck of 4*k cards without regard to suit:
unsigned n = 4 * k;
int v[n];
for (unsigned i = 0; i < k; ++i)
for (unsigned j = 0; j < 4; ++j)
v[4 * i + j] = i;
unsigned state = 1;
do {
/* process the permutation */
} while ((state = multipermute_step(v, n, state);
Actually trying to do that for k == 8 will take a while, since there are 32!/(4!)8 possible shuffles. That's about 2.39*1024. But I did do all the shuffles of decks of 16 cards in 0.3 seconds, and I estimate that I could have done 20 cards in half an hour.

C initializing a (very) large integer array with values corresponding to index

Edit3: Optimized by limiting the initialization of the array to only odd numbers. Thank you #Ronnie !
Edit2: Thank you all, seems as if there's nothing more I can do for this.
Edit: I know Python and Haskell are implemented in other languages and more or less perform the same operation I have bellow, and that the complied C code will beat them out any day. I'm just wondering if standard C (or any libraries) have built-in functions for doing this faster.
I'm implementing a prime sieve in C using Eratosthenes' algorithm and need to initialize an integer array of arbitrary size n from 0 to n. I know that in Python you could do:
integer_array = range(n)
and that's it. Or in Haskell:
integer_array = [1..n]
However, I can't seem to find an analogous method implemented in C. The solution I've come up with initializes the array and then iterates over it, assigning each value to the index at that point, but it feels incredibly inefficient.
int init_array()
{
/*
* assigning upper_limit manually in function for now, will expand to take value for
* upper_limit from the command line later.
*/
int upper_limit = 100000000;
int size = floor(upper_limit / 2) + 1;
int *int_array = malloc(sizeof(int) * size);
// debug macro, basically replaces assert(), disregard.
check(int_array != NULL, "Memory allocation error");
int_array[0] = 0;
int_array[1] = 2;
int i;
for(i = 2; i < size; i++) {
int_array[i] = (i * 2) - 1;
}
// checking some arbitrary point in the array to make sure it assigned properly.
// the value at any index 'i' should equal (i * 2) - 1 for i >= 2
printf("%d\n", int_array[1000]); // should equal 1999
printf("%d\n", int_array[size-1]); // should equal 99999999
free(int_array);
return 0;
error:
return -1;
}
Is there a better way to do this? (no, apparently there's not!)
The solution I've come up with initializes the array and then iterates over it, assigning each value to the index at that point, but it feels incredibly inefficient.
You may be able to cut down on the number of lines of code, but I do not think this has anything to do with "efficiency".
While there is only one line of code in Haskell and Python, what happens under the hood is the same thing as your C code does (in the best case; it could perform much worse depending on how it is implemented).
There are standard library functions to fill an array with constant values (and they could conceivably perform better, although I would not bet on that), but this does not apply here.
Here a better algorithm is probably a better bet in terms of optimising the allocation:-
Halve the size int_array_ptr by taking advantage of the fact that
you'll only need to test for odd numbers in the sieve
Run this through some wheel factorisation for numbers 3,5,7 to reduce the subsequent comparisons by 70%+
That should speed things up.

How to solve problems involving overlapping pairs and which data structure to use

There is a railway station whose traffic information we have, its like (arrival,departure) time pairs of trains visiting the station. Something like this T{ [1,5],[2,4],[5,9],[3,10] }. Then how to find minimum number of platforms needed to manage this traffic.
You need to find out the maximum overlap, right? This will give you the minimum number of platforms. Just initialize an array with max(times) elements equal to 0, and add then iterate through each (arrival, departure) interval, adding 1 to each element of the array that is in the interval.
Then the maximum value of any element of the array is the minimum number of platforms you'll need. This works with integer-valued intervals. The array might not be the quickest method, though. I'll leave that to you.
There is a solution in time O(n log n), where n is the number of time pairs given.
You have to answer the question: How many trains are standing in the station at the same time?
To do that, we first "normalize" the time values: Identify all time segments something interesting can happen in. To do so, sort all arrival and departure times given and eliminate duplicates.
In your example with T = {[1,5], [2,4], [5,9], [3,10]}, this results in an array
A with time points [1,2,3,4,5,9,10] and size m = 7.
Now we translate the arrival and departure time of each pair into the time segments the train is occupying the station, i. e. we find the index of the time values in the array A (via binary search). E. g. for [3, 10], we get indices 2 and 6, counting from zero.
That was it for the easy part. Sorting and matching time values with indices run in O(n log n) each. Now we have to count for each index, how many trains are standing in the station at that time. To do that efficiently, we use a segment tree.
This site gives an introduction on how to use segment trees:
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor#Segment_Trees
In the following, you'll find a implementation in C++. I hope you can adapt it to your needs. If any questions remain open, do not hesitate to ask.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/** Given a number n and n pairs of arrival and departure times of trains,
* this program calculates the number of platforms needed in time O(n log n)
* If a train arrives exactly when another one leaves the station, you need
* two platforms. */
int main () {
int n;
cin >> n;
vector< pair<int,int> > T(n);
vector< int > A(2*n);
for (int i = 0; i < n; ++i) {
int arrival, departure;
cin >> arrival >> departure;
A[2*i] = arrival;
A[2*i+1] = departure;
T[i] = pair<int,int>(arrival, departure);
}
sort(A.begin(), A.end());
int m = unique(A.begin(), A.end()) - A.begin();
// for easy indexing, we need m to be a potency of 2
int pot2m = 1; while (pot2m < m) pot2m *= 2;
// Elements pot2m ... pot2m + m represent the bottom layer of the segment tree
vector< int > segtree(2*pot2m+1, 0);
// Now let's add everything up
for (int i = 0; i < n; ++i) {
int arrival = find(A.begin(), A.end(), T[i].first) - A.begin();
int departure = find(A.begin(), A.end(), T[i].second) - A.begin();
// Now increment
int a = arrival + pot2m;
int b = departure + pot2m + 1;
while (a < b) {
if (a % 2 == 1) ++segtree[a];
if (b % 2 == 1) ++segtree[b-1];
a = (a+1) / 2;
b = b / 2;
}
}
// Find the maximum value in the cells
int a = pot2m;
int b = pot2m + m;
while (a < b) {
int i, j;
for (i = a/2, j = a; j < b-1; ++i, j+=2) {
segtree[i] += max(segtree[j], segtree[j+1]);
}
if (j == b-1) segtree[i] += segtree[j]; // To handle odd borders
a /= 2;
b /= 2;
}
cout << "You need " << segtree[1] << " platforms." << endl;
return 0;
}
I will go with your subject line question "How to solve these kind of problems and which data structure is better to handle?"
You have given an example for the above. This kind of problems are known as Optimization Problems (http://en.wikipedia.org/wiki/Optimization_problem).
Choice of data structure will be based upon space/time trade off's. So for instance one can solve the above problem by using a simple array or a hash table or maybe a graph. What is really important is sometimes it might take exponential running time in solving such problems which might make them NP-Complete/Hard. Say considering your example you have n platforms and m trains (where n & m are very large) then there is a possibility of combinatorial explosion.
Also if it results in exponential time and say is an NP-Complete/Hard problem then there are several heuristic algorithms (For an example a Travelling Salesman Problem can be solved using Ant Colony Optimization) too for solving it, maybe not the most optimal one.
Algorithms are more important here in this context than Data Structures.
Make an array of structures like this: (Time, IsArrival), where IsArrival = +1 for arrival or -1 for departure
Sort it by time key (take into account a case of equal times)
Initialize PlatformsNeeded = 0
Walk through sorted array, add IsArrival to PlatformsNeeded, remember max value

Resources