Random Numbers from preset list - c

I'm a student and in the middle of a midterm project. I am not looking for people to code this for me but I need help with part of it. I am trying to make a Blackjack game and to do that I want to set a list of 52 integers [1,1,1,1,2,2,2,2.....] one for each card in a deck. But how do take a random number from the list and cancel it out? Just like a normal deck once you take a card you can't redraw it. I know a can set a random parameter [n = rand () % 11 + 1] for the program but I want to go above and beyond to get an A

There's no way to remove a random element from an array.
What you can do instead is to swap the randomly selected element with the last element of the array. Along with this, you'll need to store the count of valid elements in the array in a variable array_size_validand decrement that value every time the swapping takes place.
This way you're random index generation function will become:
rand_index = rand () % array_size_valid;

Here is an trivial way: Say you have an array, containing 52 integers:
int deck[52];
And you have initialised it to the value you want, such as 1, 1, 1, 1, 2, 2, 2, 2, .....
When a card is drawn, set the corresponding array element to -1 (or any value other than the original ones):
int drawCard(int deck[])
{
do{
int randIndex = rand () % 52;
} while(deck[randIndex] == -1);
int drawnCard = deck[randIndex];
deck[randIndex] = -1;
return drawnCard;
}
Although this approach may not be efficient enough, it does work, so I think it may be helpful to beginners like you.

You can use a shuffling algorithm, like this: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle. The Fisher - Yates shuffle starts with an array, then it switches every item of the array with a random item from the array. It is also possible to remove items one by one, but it is more complicated. You can remove items one by one randomly using a binary tree. Store the total number of items under each node. Every time, to remove an item, generate a random number a greater than or equal to 0 and less than the number of items left. Start with the root. Go to the left child if a is less than the number of items under the left child. Otherwise, let a be a-, and go to the right child. Do this recursively. But removing items one by one is more complicated. It is better to just use a shuffling algorithm.

Related

C: More Efficient Way of Checking for Equivalence in Array?

I have the function working, but I am looking to see if there's a more efficient way of checking if there are three of a kind in my hand of cards so I don't need so many nested loops. I'm not sure if there even is though. I am using enumerations and structures for my card in the deck.
There are multiple ways you can do this. The best way depends on the type of entries you have in the array?
Are the total cards limited? What I mean is that is the maximum value that can be in the array bounded? (Since they are cards I guess they can go from 1-13).
Then the best option would be to make another array counter of size 13 and initialize it with 0. They iterate over all the elements and then increment the counter of the card you see. At any point if the counter == 3 return true else at the end false.
The implementation would be
int counter[13] = {0};
for ( i = 0; i < 5; i++ ){
card = hands[i].cardRank;
counter[card]++;
if (counter[card] == 3)
return true;
return false;
If the values of the card is not bounded, you can use a hashmap in a similar way.
If hashmap datastructure is not available you, you will have to use another approach.
Here you will first sort the array. So if there are 3 occurrences they will come together. And in a single loop you can check them. For every element check if the next and the next to next element is the same as it. If yes return true.
Else finally return false.
I think the code for that would be easy to implement.
I can post if you are not able to figure out.
You could make an integer array with one element for each card rank. This will count how many cards of that rank are in the hand. Iterate through the hand, and for each card, increment the rank-count array for the corresponding rank. Then iterate through the rank-count array and see if any values equal 3. This method would also work well for finding four of a kind. If you iterate through the rank-count array in descending order, you can find the highest rank group.
If your hand is sorted, you can do this :
for(int i = 0 ; i < 5 - 2; ++i){
if (hand[i].cardRank == hand[i+1].cardRank && hand[i].cardRank == hand[i+2].cardRank){
// triplets found
}

Implementing Radix sort in java - quite a few questions

Although it is not clearly stated in my excercise, I am supposed to implement Radix sort recursively. I've been working on the task for days, but yet, I only managed to produce garbage, unfortunately. We are required to work with two methods. The sort method receives a certain array with numbers ranging from 0 to 999 and the digit we are looking at. We are supposed to generate a two-dimensional matrix here in order to distribute the numbers inside the array. So, for example, 523 is positioned at the fifth row and 27 is positioned at the 0th row since it is interpreted as 027.
I tried to do this with the help of a switch-case-construct, dividing the numbers inside the array by 100, checking for the remainder and then position the number with respect to the remainder. Then, I somehow tried to build buckets that include only the numbers with the same digit, so for example, 237 and 247 would be thrown in the same bucket in the first "round". I tried to do this by taking the whole row of the "fields"-matrix where we put in the values before.
In the putInBucket-method, I am required to extent the bucket (which I managed to do right, I guess) and then returning it.
I am sorry, I know that the code is total garbage, but maybe there's someone out there who understands what I am up to and can help me a little bit.
I simply don't see how I need to work with the buckets here, I even don't understand why I have to extent them, and I don't see any way to returning it back to the sort-method (which, I think, I am required to do).
Further description:
The whole thing is meant to work as follows: We take an array with integers ranging from 0 to 999. Every number is then sorted by its first digit, as mentioned above. Imagine you have buckets denoted with the numbers ranging from 0 to 9. You start the sorting by putting 523 in bucket 5, 672 in bucket 6 and so on. This is easy when there is only one number (or no number at all) in one of the buckets. But it gets harder (and that's where recursion might come in hand) when you want to put more than one number in one bucket. The mechanism now goes as follows: We put two numbers with the same first digit in one bucket, for example 237 and 245. Now, we want to sort these numbers again by the same algorithm, meaning we call the sort-method (somehow) again with an array that only contains these two numbers and sorting them again, but now my we do by looking at the second digit, so we would compare 3 and 4. We sort every number inside the array like this, and at the end, in order to get a sorted array, we start at the end, meaning at bucket 9, and then just put everything together. If we would be at bucket 2, the algorithm would look into the recursive step and already receive the sorted array [237, 245] and deliver it in order to complete the whole thing.
My own problems:
I don't understand why we need to extent a bucket and I can't figure it out from the description. It is simply stated that we are supposed to do so. I'd imagine that we would to it to copy another element inside it, because if we have the buckets from 0 to 9, putting in two numbers inside the same bucket would just mean that we would overwrite the first value. This might be the reason why we need to return the new, extended bucket, but I am not sure about that. Plus, I don't know how to go further from there. Even if I have an extened bucket now, it's not like I can simply stick it to the old matrix and copy another element into it again.
public static int[] sort(int[] array, int digit) {
if (array.length == 0)
return array;
int[][] fields = new int[10][array.length];
int[] bucket = new int[array.length];
int i = 0;
for (int j = 0; j < array.length; j++) {
switch (array[j] / 100) {
case 0: i = 0; break;
case 1: i = 1; break;
...
}
fields[i][j] = array[j]
bucket[i] = fields[i][j];
}
return bucket;
}
private static int[] putInBucket(int [] bucket, int number) {
int[] bucket_new = int[bucket.length+1];
for (int i = 1; i < bucket_new.length; i++) {
bucket_new[i] = bucket[i-1];
}
return bucket_new;
}
public static void main (String [] argv) {
int[] array = readInts("Please type in the numbers: ");
int digit = 0;
int[] bucket = sort(array, digit);
}
You don't use digit in sort, that's quite suspicious
The switch/case looks like a quite convoluted way to write i = array[j] / 100
I'd recommend to read the wikipedia description of radix sort.
The expression to extract a digit from a base 10 number is (number / Math.pow(10, digit)) % 10.
Note that you can count digits from left to right or right to left, make sure you get this right.
I suppose you first want to sort for digit 0, then for digit 1, then for digit 2. So there should be a recursive call at the end of sort that does this.
Your buckets array needs to be 2-dimensional. You'll need to call it this way: buckets[i] = putInBucket(buckets[i], array[j]). If you handle null in putInBuckets, you don't need to initialize it.
The reason why you need a 2d bucket array and putInBucket (instead of your fixed size field) is that you don't know how many numbers will end up in each bucket
The second phase (reading back from the buckets to the array) is missing before the recursive call
make sure to stop the recursion after 3 digits
Good luck

quicksort, can it be made to output the first m sorted values in an N dimension array, thereby being faster than a full N sort

Quicksort is a well known algorithm, but it's complex to decipher the C (for me). The inline version speed things up a lot http://www.corpit.ru/mjt/qsort.html‎.
However, could it be easily converted to output the first m samples of an N-element array ?
So a call that would simply stop the sort after the first m samples are sorted ? I suspect not as it does a quicksort into blocks then stitches blocks together for the final output. If I make the initial quicksort block size the size of m then I'm in a bad place, not taking advantage of the clever stuff in qsort.
Thanks in advance
Grog
Use Quickselect, as #R.. suggested, to get the first k elements, then sort them. Running time is O(N) to get the elements, and O(k log k) to sort them.
However, emperical evidence suggests that if the number of items to select (k) is less than 1% of the total number of elements (N), then using a binary heap will be faster than Quickselect followed by sort. When I had to select 200 items from a list of 2 million, the heap selection algorithm was a lot faster. See the linked blog for details.
(Restate the question: given N items, find the largest m of them.)
A simple solution is a priority queue. Feed all N items into the queue, then pop the top m items off the list. Feeding the N items in will be O(N log m). Each individual pop operation is O(log m), so removing the top n items would be O(m log m).
An in-place algorithm should be relatively straightforward. We an array of N elements. Each position in the array is numbered, with a number between 1 and N (inclusive). For each position in the array, take its position and divide by two (rounding down if necessary), and defining that position as its parent. Every position, apart from position 1, will have a parent. And most positions (not all) will have two children. For example:
node position: 1 2 3 4 5 6 7 8 9 ...
parent: - 1 1 2 2 3 3 4 4 ...
We want to swap the nodes until each node has a value less than (or equal to) its parent. This will guarantee that the largest value is in position 1. It is quite easy to reorder an array to have this form. Simply go through the nodes in order from position 1 to N, and call this function on it once:
void fixup_position(int x) {
if(x==1)
return;
int parent_position = (x/2) ; // rounding-down where necessary
if (data[x] > data[parent_position]) {
swap(data[x], data[parent_position]);
check_position(parent_position); // note this recursive call
}
}
for(x = 1; x <= N; ++x) {
fixup_position(x);
}
(Yes, I'm counting the array with position one, not zero! You'll have to take this account when implementing it for real. But this is easier to understand the logic of priority queue.)
The average number of recursive calls (and therefore swaps) is a constant (2, if I remember correctly). So this will be pretty quick, even with large datasets.
It's worth taking a moment to understand why this is correct. Just before calling fixup_position(x), every position up to, but not including x, are in a 'correct' state. By 'correct' I mean that they're not fully sorted, but each node is less than its parent. A new value is introduced (at position x), and will 'bubble up' through the queue. You might worry that this will invalidate other positions, and their parent-child relationship, but it won't. Only one node at a time will be in an invalid state, and it will keep bubbling up to its rightful place.
This is the O(N) step that will rearrange your array into a priority queue.
Removing the top n items. After the above method, it's clear that the biggest number will be in position 1, but what about the second-biggest, and third-biggest, and so on? What we do is we pop one value at a time from position 1 and then rearrange the data so that the next-biggest value is moved into position 1. This is slightly more complex than the fixup_position.
for(int y = 1; y <= m; ++y) {
print the number in position 1 .... it's the next biggest number
data[1] = -10000000000000; // a number smaller than all your data
fixup_the_other_way(1); // yes, this is '1', not 'y' !
}
where fixup_the_other_way is:
void fixup_the_other_way(int x) {
int child1 = 2*x;
int child2 = 2*x+1;
if(child1 > N) // doesn't have any children, we're done here
return;
if(child2 > N) { // has one child, at position[child1]
swap(data[x], data[child1]);
fixup_the_other_way(child1);
return;
}
// otherwise, two children, we must identify the biggest child
int position_of_largest_child = (data[child1]>data[child2]) ? child1 : child2;
swap(data[x], data[position_of_largest_child]);
fixup_the_other_way(position_of_largest_child);
return;
}
This means we print out the biggest remaining item, then replace that with a really small number and force it to 'bubble down' to the bottom of our data structures.
There are two ways to solve the problem efficiently:-
1.> Priority Queues
Algorithm: -
Insert first n items into Priority Queue with max heap
Peek on max element to check if current element compared is less than that
if less delete top element and add current
Do steps for all N-n elements.
2.> Your Problem can be reduced to selection problem : -
Algorithm
Do randomized selection for nth element on N elements (O(N) in average case)
sort first n elements using qsort or any other efficient sorting algorithm
Using both algorithms you would get average case O(N) performance

Saving randomly generated numbers in C

I'm trying to find the best way to save a set of randomly generated numbers so they can be recalled later in another function. Basically I have one function that generates the numbers and makes sure they have no repeats, but I need another function that will search the list of numbers to see if the user has picked one of those numbers. whenever I call the random number function within my search function, I just get a list of different random numbers.
Basically I'm just trying to figure out the best way to either save this array of numbers so it doesn't give me knew numbers the next time I call the function, or the best way to pass it on to the next function.
here is the random number generator function, in case you wanted to see what I'm trying to pass onto the next function.
int i, j;
/*generates the set of random numbers*/
for(i = 0; i < MAX; i++) {
random = rand() % 101;
/*checks to to make sure there is no repeats*/
for (j = 0; j < i; j++) {
if (lucky[j] == random) {
random = rand() % 101;
}
}
lucky[i] = random;
printf("%3d",random);
}
Create a new array first:
int *lucky = malloc(amount_of_numbers_you_want * sizeof(int));
Then fill it with random numbers as usual, and then return it. For example:
int* generate_random_numbers(int amount)
{
int *lucky = malloc(amount * sizeof(int));
/* Fill lucky[] with 'amount' unique random numbers. */
return lucky;
}
Then, whenever you call that function, save the pointer it returns somewhere. Do not forget to free() that pointer when you no longer need it, or else you will leak the memory it occupies.
Since this looks like homework, I'm not giving you full code, but rather a general methodology of how you deal with this kind of problem by using dynamically allocated arrays.
So, first of all, that does not ensure the random number are always different:
if your list has [0.1,0.24,0.555] and you add a new RNG with 0.24, it repeats, but can generate a 0.1 which is also stored in lucky[] (and is thus repeated, as you don't like). It is not very probable, but possible.
The way you want is to have a while(), and only when the new RNG is checked against all the list, it is added.
Finally, generally the best way to save a list of RNGs is to set the seed of the RNG. Given a seed "a", the list of numbers generated by the seed "a" is always the same. In that case, your function can even be checking for non-repetitive RNGs, because the result will always be the same.
#Nikos has given correct answer.
You can allocate memory for an array in caller function as well and pass that to random number generating function. Whatever you do make sure lucky isn't locally defined array. Moreover, your logic to generate numbers seems to be wrong (without repetition). As pointed out by #Nikos this seems to be a school assignment, I will just point obvious mistakes.
a) you don't take care of case where second time generated number (second call to random if first random matches with already existing list) is being checked with older set of generated values correctly.
b) random generating function gives you random number between 0 to RAND_MAX and RAND_MAX % 101 isn't 0. That means the probability of getting random number generated isn't uniform.

Problems with my random number generator

Im learning basic C on my own and trying to create a poker client. I have an array with cards (called kortArray) and a players hand (called kortHand). My implementation does not shuffle the deck, but add all 52 cards in sequence and then randomly selecting 5 cards from the deck. I've added a flag (called draget) which tells if a card has been picked up befor or not.
Now, when I run the algorithm below, it usually generates five random numbers which makes the player's or computer's hand. But sometimes it generates less then five numbers, even though I've specifically stated to generate five accepted values.
I have two loops, one that runs five times, and the other is nested and runs until it finds a card which hasn't yet been picked. The printf in the middle tells me that this algorithm doesn't always generate five accepted numbers, and when that happens the player's hand contains cards with nonsense-values.
srand((unsigned)(time(0)));
for(i = 0; i < 5; i++) {
int x = rand()%52 + 1;
while (kortArray[x].draget!=1) {
x = rand()%52 + 1;
if (kortArray[x].draget != 1) {
printf("%i\n", x);
kortArray[x].draget = 1;
kortHand[i] = kortArray[x];
}
}
}
The problem still lies in the +1 for the random numbers.
Also, you are first checking in the the first assignment to x if the card is already picked, and than you assign it to an other card.
Why not use something like:
int nr_cards_picked = 0 /* Number of uniquely picked cards in hand */
/* Continue picking cards until 5 unique cards are picked. */
while (nr_cards_picked < 5) {
x = rand() % 52; /* Take a random card */
if (kortArray[x].draget == 0) {
/* Pick this card. */
kortArray[x].draget = 1; /* Card is picked */
kortHand[i] = kortArray[x]; /* Add picked card to hand */
nr_cards_picked++;
}
}
Forgive compiler errors; I don't have a compiler near here.
This case you only have one time a random number call.
Theoretically it might never end but this is not likely.
You have:
int x = rand()%52+1;
while (kortArray[x].draget!=1){
x = rand()%52;
Arrays in C are indexed starting at 0. Your first call to rand() will generate a value starting at 1. Assuming that you declared kortArray[] to hold 52 values, there is about a 2% chance that you will overrun the array.
Your first call to rand() generates values in the range 1..52. Your second call generates 0..51. ONE OF THEM IS WRONG.
A few things of note.
First of all, random number generators are not guaranteed to be random if you do a mod operation on them. Far better is to divide it out into the 52 segments, and choose like that.
Secondly, you would be far better off moving your call to generate a random number inside the while loop to the end, or just not generate one at the beginning of the for loop.
Where your problem is coming into play is that you are sometimes leaving the while loop without actually entering it, because you are randomly generating a number before you enter the loop.
Given all of this, I would do code somewhat as follows:
srand((unsigned)(time(0)));
for(i=0;i<5;i++){
x=-1;
while (kortArray[x].draget!=1){
x = floor(rand()*52);
}
printf("%i\n", x);
kortArray[x].draget=1;
kortHand[i]=kortArray[x];
}
The nested loop is only entered when kortArray[x].draget is not 1. So everytime it is 1, nothing is done and no card is assigned. First make sure you have a unique x and then in all cases update kortHand[i]
I'd suggest a different algorithm:
create a random number between 0 and number of cards in deck
assign the card from that position to the appropriate hand
swap the last card to that postion
decrease the number of cards in the deck by 1.
continue with 1 until the necessary number of cards are dealt.
This way, you get rid of the flag and you can guarantee linear performance. No need to check whether a card has already been dealt or not.

Resources