Preventing repetition of same number that created randomly - c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (void) {
int i,j,z,w,c; /* counter*/
int ticket[6],n[6];
int a; /*numbers of one ticket*/
int x; /* Random numbers of tickets*/
int num; /*Quantity of tickets*/
int loser = 0; /*initialize the number of known-tickets*/
int threeknown = 0;
int fourknown = 0;
int fiveknown = 0;
int winner = 0;
srand (time(NULL));
printf ("Please enter the lucky ticket numbers between 0 and 50\n");
for (i=0;i<6;i++) { /* loop for entering numbers of ticket from keyboard*/
scanf ( "%d",&a);
if (a<50 && a>0){
ticket[i] = a;
}
else {
printf ("\a ERROR: Please enter number between 0 and 50\n");
i--; /* enter again */
}
}
printf ("Lucky ticket is:\n");
for (i=0;i<6;i++) {
printf ("%3d",ticket[i]);
}
printf ("\n");
printf ("Please enter the quantity of tickets\n\a");
scanf ("%d",&num);
for (z=0;z<num;z++) { /* For each ticket */
for (j=1;j<=6;j++) {
x = 1 + rand()%49;
n[j] = x;
printf ("%3d",n[j]);
}
printf("\n\n");
}
for (z=0;z<num;z++){ /*counter for each ticket control */
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3] && ticket[4]==n[4] && ticket[5]==n[5]) {
winner += 1;
}
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3] && ticket[4]==n[4]) {
fiveknown += 1;
}
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2] && ticket[3]==n[3]) {
fourknown += 1;
}
if (ticket[0]==n[0] && ticket[1]==n[1] && ticket[2]==n[2]) {
threeknown += 1;
}
else {
loser += 1;
}
}
printf ("Number of winners : %d\n",winner);
printf ("Number of five-knowns : %d\n",fiveknown);
printf ("Number of four-knowns : %d\n",fourknown);
printf ("Number of three-knowns : %d\n",threeknown);
printf ("Number of losers : %d\n",loser);
system ("PAUSE");
return 0;
}
I have project about C coding Bingo Program. I need to maintain a winner ticket from keyboard between 0 and 50 (12 34 23 11 47 4) and then I need to generate tickets randomly. In these tickets none of them have the same number and the sorting is not important. For example ( 23 12 10 4 9 46 ). My question is to how to have these kind of tickets ? I don't want to have this kind of tickets ( 12 43 20 12 9 4 )

Build an array of the fifty acceptable values, choose one, and then remove it from the array.
Since the order in the array is not important, you can remove it at little cost by overwriting it with the last value and decreasing the "array count" variable.
void RemoveFromArray(int* arr, size_t *pNumberOfElements, size_t indexToRemove)
{
//Note: I'm not putting the error/bounds checking because it's not what the question is about.
size_t indexLast = *pNumberOfElements - 1;
arr[indexToRemove] = arr[indexLast];
(*pNumberOfElements)--;
}
void ChooseRandom6of50(int* random6ints)
{
int arr[50];
size_t nElements = 50;
{
size_t i;
for(i=0 ; i<50 ; i++)
arr[i] = (int)(i+1); //Fill with values 1 to 50
}
{
size_t iDest;
for(iDest=0 ; iDest<6 ; iDest++)
{
int rnd = rand() % nElements; //The real code should use the more elaborate random formula
size_t randIndex = rnd;
random6ints[iDest] = arr[randIndex];
RemoveFromArray(arr, &nElements, randIndex);
}
}
}

For a small number of tickets picked, the easiest way is to draw tickets randomly as you did already, but draw again if the ticket is already in the lot of drawn ticktes until you have a new ticket:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX
int contains(int ticket[], int n, int which)
{
while (n-- > 0) {
if (ticket[n] == which) return 1;
}
return 0;
}
void draw(int ticket[], int n, int m)
{
int i, t;
if (n > m) return;
for (i = 0; i < n; i++) {
do {
t = rand() % m;
} while (contains(ticket, i, t));
ticket[i] = t;
}
}
int main (void)
{
int ticket[6];
int i;
draw(ticket, 6, 50);
for (i = 0; i < 6; i++) printf("%4d", ticket[i]);
printf("\n");
return 0;
}
Note that the draw function does not do anything if the number of tickets to draw, n, is bigger than the tickets available, m, because that would lead to an infinite loop. If n == m the draw is like shuffling, albeit in a very inefficient way. (The draw function should probably return an error code or abort the program in that case, but in oder to keep things simple, I've left that out.)
The contains function should also come in handy if you want to compare the user's tickets with the draw. (Also, it would look more like programming if you could turn your variable threeknown, fiveknown and so on into an array hits[7].)

Related

Need to generate 4 random numbers without repetition in C programming. 1 to 4

I want to generate numbers 1 to 4 in a random fashion using C programming.
I have made provision to print a[0] directly in a while loop and for any further element the program checks whether the new number from a[1] to a[3] is same as any of the previous elements. A function has been created for the same. int checkarray(int *x, int y).
The function checks current element with previous elements one by one by reducing the passed address. If it matches the value it exits the loop by assigning value zero to the condition variable (int apply).
return apply;
In the main program it matches with the int check if check==1, the number is printed or else the loop is repeated.
Problem faced: The number of random numbers generated is varying between 2 and 4.
e.g
2 4
2 4 3
1 3 3 4
etc
Also repetition is there sometimes.
#include <stdio.h>
#include <conio.h>
int checkarray(int *x, int y);
void main() {
int a[4], i = 0, check;
srand(time(0));
while (i < 4) {
a[i] = rand() % 4 + 1;
if (i == 0) {
printf("%d ", a[i]);
i++;
continue;
} else {
check = checkarray(&a[i], i);
}
if (check == 1) {
printf("\n%d ", a[i]);
} else {
continue;
}
i++;
}
getch();
}
int checkarray(int *x, int y) {
int arrcnt = y, apply = 1, r = 1;
while (arrcnt > 0) {
if (*x == *(x - 2 * r)) {
apply = 0;
exit(0);
} else {
arrcnt--;
r++;
continue;
}
}
return apply;
}
Let's look at the checkarray function, which is supposed to check if a number is already present in the array.
It is called this way:
check = checkarray(&a[i], i);
Where a is an array of 4 integers and i is the actual index, so it tries to scan the array backwards looking for any occurrences of a[i]
int checkarray(int *x,int y)
{
int arrcnt=y,apply=1,r=1;
while(arrcnt>0)
{
if(*x==*(x-2*r))
// ^^^ Why? This will cause an out of bounds access.
{
apply = 0;
exit(0); // <-- This ends the program. It should be a 'break;'
}
else
{
arrcnt--;
r++;
continue;
}
}
return apply;
}
Without changing the interface (which is error prone, in my opinion) it could be rewritten as
int check_array(int *x, int y)
{
while ( y )
{
if ( *x == *(x - y) )
return 0;
--y;
}
return 1;
}
Testable here.
There are many other issues which should be addressed, though, so please, take a look to these Q&A too.
Does "n * (rand() / RAND_MAX)" make a skewed random number distribution?
Why do people say there is modulo bias when using a random number generator?
Fisher Yates shuffling algorithm in C
int main() vs void main() in C
Why can't I find <conio.h> on Linux?
Your approach is tedious but can be made to work:
there is no need to special case the first number, just make checkarray() return not found for an empty array.
you should pass different arguments to checkarray(): a pointer to the array, the number of entries to check and the value to search.
you should not use exit(0) to return 0 from checkarray(): it causes the program to terminate immediately.
Here is a modified version:
#include <stdio.h>
#include <conio.h>
int checkarray(int *array, int len, int value) {
int i;
for (i = 0; i < len; i++) {
if (array[i] == value)
return 0;
}
return 1;
}
int main() {
int a[4], i = 0, value;
srand(time(0));
while (i < 4) {
value = rand() % 4 + 1;
if (checkarray(a, i, value)) {
printf("%d ", value);
a[i++] = value;
}
}
printf("\n");
getch();
return 0;
}

Finding the n-th prime number that is palindrome in base K

I recently asked a question about finding whether a number is palindrome in base K or not and I get my answer.
My Recent Question
Now I have a more complicated question, We will get two numbers n and k, and we must find the n-th prime number that is palindrome in base K.
For example if we get 8 and 10, we have 2 3 5 7 11 101 131 151 which are palindrome and prime and so the answer is 151. Another example is 4 2 we have 3 5 7 17 respectively 11 101 111 10001 in base 2 which are prime and palindrome in base so the answer is 17.
n and k are given such that the answer is at most, 1E7.
I submit my program in a judge system and It gave wrong answer in some cases and also Time Limit error in one case. I don't know which part of my algorithm is wrong and what part of it is not optimised.
Note that I am not allowed to use array,vector and strings and also I cannot use libraries more than stdio.h and math.h. It is my program, Can anyone find any problems in it: (I defined intPow because the pow function in math, gives a float and sometime it causes problems)
#include <stdio.h>
#include <math.h>
int primeCheck ( int n);
int palindrome ( int n,int base);
int digitCountBase (int n , int base);
int intPow (int a , int b);
int main()
{
int n;
int base;
scanf("%d %d",&n,&base);
int counter = 0;
int i =2;
int firstRound =1;
while (counter!=n)
{
if (primeCheck(i))
{
if (palindrome (i,base))
{
counter++;
}
}
if (counter ==n)
{
break;
}
if (firstRound)
{
i++;
firstRound=0;
}
else{i+=2;}
}
printf("%d",i);
return 0;
}
int primeCheck ( int n)
{
if (n<2)
{
return 0;
}
if (n==4)
{
return 0;
}
else if (n<=5)
{
return 1;
}
if (n%2 ==0 || n%3 ==0 || n% 5 ==0)
{
return 0;
}
int i =5;
int limit = sqrt(n)+2;
for (int i =5;i<=limit;i+=6)
{
if (n%i==0||n%(i+2)==0)
{
return 0;
}
}
return 1;
}
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
while (n>0&& digitCount >0)
{
if (n%base != (n/power)&&digitCount!=1)
{
isTrue =0;
return 0;
}
n = n- power;
n=n/base;
power = power /base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
int digitCountBase (int n , int base)
{
int digits=0;
while (n)
{
digits++;
n = n / base;
}
return digits;
}
int intPow (int a , int b)
{
int result = 1;
for (int i=1;i<=b;i++)
{
result = result * a;
}
return result;
}
Solution: change palindrome to
int palindrome ( int n,int base)
{
int isTrue = 1;
int digitCount = digitCountBase(n,base);
int power = intPow(base,digitCount-1);
int original = n;
while (n>0&& digitCount >0)
{
if (n%base != (original/power) % base &&digitCount!=1)
{
isTrue =0;
return 0;
}
n=n/base;
power = power /base;
digitCount=digitCount-2;
}
return isTrue;
}
How did I find the error:
You are doing only 2 things, primality testing and palindrome testing, so makes sense to check if these are working fine.
Primality testing is easy, count primes from 1 to 10^7 and compare to known values on google. In this case, this works
To test palindrome, pick a working solution from the internet (even if you can´t submit their solution that uses arrays/strings, you can test with them!). Then iterate from 1 to 10^7 in a certain base and check that both functions return the same.
Testing with base 3, quickly saw that 56 was not giving same output. And the incorrect one was yours.
Then its a matter of fixing your function, which you now know which one is the problem and even have an example of where its not working

Deleting Duplicates in array and replacing them with unused values

My objective for this program is to let the user determine the size of the array and dynamically allocate memory for whatever size they choose. Once the user defines the size of the array, random numbers that do no exceed the size of the array are placed into all of the allotted positions. Where I am having issues is removing duplicates from the array and replacing them with a value that is not being used,
Example:
Please enter the size of the array:
User Input: 5
Output of code: 5, 3, 3, 1, 2
I would need it to be something like this:
Please enter the size of the array:
User Input: 3
Output of program: 3, 1, 2
Currently reading "C Programming - A Modern Approach" by K.N. King (Second Edition).
if someone could point me in the right direction on how to approach this, it would be much appreciated.Here is my code thus far.
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0
typedef int bool;
int main() {
int *UserData;
int TempPost;
int replace;
int UserInput;
int i;
int result;
bool digit_seen[UserInput];
int digit;
srand ((unsigned) time(NULL));
printf("Please enter the size of the array using a whole number: \n");
scanf("%d", &UserInput);
UserData = malloc(sizeof(int) * (UserInput ) +1);
for(i=0; i < UserInput; i ++) {
result = (( rand() % UserInput) + 1);
}
// check for duplicate values while putting values in array
while(UserInput>0){
digit = UserInput % UserInput;
if(digit_seen[digit])
break;
digit_seen[digit] = true;
UserInput /= UserInput;
if(UserInput > 0)
printf("Repeated digit \n");
else
printf("No repeated digit \n");
}
// Sorting the array using a Bubble sort
while(1){
replace = 0;
for (i=0; i<(UserInput - 1); i++){
if(UserData[i]>UserData[i+1]){
TempPost = UserData[i];
UserData[i] = UserData[i+1];
UserData[i+1] = TempPost;
replace = 1;
}
}
if(replace==0){
break;
}
}
printf("%d \n", result);
return 0;
}
It's not the most efficient way, but you can do it as you're generating the random numbers. When you pick a random number, go through all the previous elements of the array and see if it's already been used. Keep looping until you pick an unused number.
for (i = 0; i < UserInput; i++) {
do {
result = ( rand() % UserInput) + 1;
} while (in_array(result, UserData, i-1));
UserData[i] = result;
}
int in_array(int val, int* array, int array_size) {
for (int i = 0; i < array_size; i++) {
if (array[i] == val) {
return 1;
}
}
return 0;
}
A slightly more efficient way to do it is to initialize the array to 0. Then instead of picking random numbers, pick a random index to fill in, and repeat this until you pick an index that contains 0.
UserData = calloc(UserInput, sizeof(int));
for (i = 1; i <= UserInput; i++) {
int index;
do {
index = rand() % UserInput;
} while (UserData[index] != 0)
UserData[index] = i;
}
What you can do is shuffle the array instead. Just fill the array with all the numbers in order using a simple for loop, then shuffle it with something like this:
//read user input
//create array and fill with all the numbers in order
//[0,1,2,3,4,5 .. ... ]
int index, temp;
// size is the size of the array
for(int i = 0; i < size; i++)
{
index = rand()%size;//random place to pick from
temp = array[i];
array[i] = array[index];
array[index] = temp;
}
This is a lot more effecient -and less error prone- than your current approach.

issues randomly populating a 2d array of structure type in C

I'm trying to populate a 20x20 matrix where each entry is of structure type. My goal is to randomly assign 100 ants and 5 doodlebugs on this 2D array. Even though I got it to work, I don't always get the amount of ants or doodlebugs I need in the matrix. I added a counting function to always verify how many of them I have each time I run the program, but I'm always slightly short. I'm trying to force those number to work (100 ants and 5 doodlebugs) by using a do/while loop in my populating function, although it's not working. Can someone spot where is my logic is failing me?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define N 20
struct cellState {
int emptyInt;
int antInt;
int dBInt;
char emptyChar;
char antChar;
char dBChar;
};
struct cellState gridState[N][N];
// function to populate world
void pop_mtx(struct cellState gridState[N][N], int antsNeeded, int dBNeeded) {
int i, j;
do {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if ((gridState[i][j].emptyInt = rand() % 3) == 0) {
gridState[i][j].emptyChar = '.';
} else
if (((gridState[i][j].antInt = rand() % 3 == 1) && antsNeeded != 0)) {
gridState[i][j].antChar = 'a';
antsNeeded--;
} else
if (((gridState[i][j].dBInt = rand() % 3 == 2) && dBNeeded != 0)) {
gridState[i][j].dBChar = 'D';
dBNeeded--;
}
}
}
} while (dBNeeded != 0 && antsNeeded != 0);
}
//function to display current state of the world
void display_mtx(struct cellState gridState[N][N]) {
int i, j;
char charToDisplay;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
charToDisplay = 'a';
else
if (gridState[i][j].dBChar == 'D')
charToDisplay = 'D';
else
charToDisplay = '.';
printf("%c ", charToDisplay);
}
printf("\n");
}
printf("\n\n");
}
//function to count ants and doodlebugs
void count_mtx(struct cellState gridState[N][N]) {
int i, j, antCount = 0, dBcount = 0;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (gridState[i][j].antChar == 'a')
antCount++;
else
if (gridState[i][j].dBChar == 'D')
dBcount++;
}
}
printf("ant count: %i, doodlebug count: %i\n", antCount, dBcount);
}
int main(void) {
srand((unsigned int)time(NULL));
//populate grid state with 5 doodlebugs and 100 ants
int antsNeeded = 100, dBNeeded = 5;
pop_mtx(gridState, antsNeeded, dBNeeded);
count_mtx(gridState);
display_mtx(gridState);
}
There are several problems. First, each time you call rand() you obtain a different value, so it is possible that none of the three tests pass. You should call rand () once and save the value.
Second, there is nothing that guarantees that over NxN calls of rand() you will get as many ones and twos as you need. The outer loop is therefore necessary. You should also preserve already populated squares from one iteration to the next because it might take a long time before you reach an iteration that produces enough ones and twos.
Third, this method is biased toward the squares at the beginning of the grid. It will not give you one out of all possible distributions of 100 ants and 5 doodlebugs over 400 squares with equal probability.
Here is the proper way to do it:
Consider the grid as a uni-dimensional array. First fill it, in order, with 100 ants, 5 doodlebugs, and empty spaces. Then perform a random shuffle of the array.
This procedure will return each possible distribution of the ants and doodlebugs on the grid with equal probability.

How to check if the numbers smaller than an integer variable contain a specific digit

I have a question: I’m supposed to build a program where when I enter an integer below a hundred, all numbers smaller than said integer and containing the digit “3″ appear on the screen (etc, if I enter 14, the numbers “3, 13″ should appear).
However, there’s something wrong with my code, please help! Thank you!
The code:
#include <stdio.h>
int main(int argc, const char * argv [])
{
int wholenumber;
printf("百以内の整数を入力してください\n");
scanf_s("%d", &wholenumber);
while(0 <wholenumber)
{
wholenumber--;
while(0 < wholenumber){
wholenumber = 3 %10;
wholenumber = 3 /10;
if (wholenumber == 3);
{printf("%3d",wholenumber);}
}
}
return 0;
}
If x is an integer between 0 and 99, the following will check whether either of its digits is a 3:
if (x / 10 == 3 || x % 10 == 3) {
...
}
I leave the rest as an exercise for the reader.
I have no idea what your intention was with this code:
wholenumber = 3 % 10;
wholenumber = 3 / 10;
First line sets the variable to 3, the second to 0.. which forces the program to exit from the loop.
Code:
#include<stdio.h>
int main()
{
int i,num;
int t1,t2; // Variable to store data temporary
printf("\nEnter the number : \n");
scanf("%d",&num);
for(i=0;i<num;i++)
{
t1= i/10;
t2= i%10;
if((t1==3) || (t2 ==3)) //check if number has 3 in it
printf(" %d", i);
}
return 0;
}
This is code which is required.Thanks to #amulous for pointing out mistake.
Note: It is assumed that entered number is less than 100 as required by user who asked question.
#include <stdio.h>
int contain3(int n){
if(n == 0) return 0;
return (n % 10 == 3) ? 1 : contain3(n/10);
}
int main(void){
int i, wholenumber;
printf("百以内の整数を入力してください\n");
scanf_s("%d", &wholenumber);
for(i=3;i<wholenumber;++i)
if(contain3(i))
printf("%3d", i);
return 0;
}
#include <stdio.h>
#include <limits.h>
int main(void){
int i, wholenumber;
int data[]={3,13,23,30,31,32,33,34,35,36,37,38,39,43,53,63,73,83,93,INT_MAX};
printf("百以内の整数を入力してください\n");
scanf_s("%d", &wholenumber);
for(i=0;data[i]<wholenumber;++i)
printf("%3d", data[i]);
return 0;
}
OP solution is conceptionallly close but needs changes.
The while() loop test destroys wholenumber. The test for '3' containment should use a copy of wholenumber
the syntax of wholenumber = 3 /10; should be wholenumber_test /= 10;
other syntax errors.
void whole(int wholenumber, int digit) {
while (0 < wholenumber) {
int test = wholenumber; // form test value
while (0 < test) {
if ((test%10) == digit) {
printf("%3d\n", wholenumber);
break; // no need to test other digits
}
test /= 10; // move onto next digit
}
wholenumber--;
}
}
You can write this more efficiently, and this will work for any upper limit:
#include <stdio.h>
int main(int argc, const char * argv [])
{
int wholenumber;
printf("百以内の整数を入力してください\n");
scanf("%d", &wholenumber);
for (int tens = 1; tens < wholenumber; tens *= 10) {
for (int i = 3 * tens; i < wholenumber; i+= 10*tens) {
printf("%3d\n", i);
}
}
return 0;
}

Resources