My own random number generator - c

I want to make a random number generator where the user specifies the range and amount of generated numbers. I want it to make every number unique (no repeat). This is what I've done so far (it generates but some of them repeat, why?)
#include <time.h>
#include <stdio.h>
#include <windows.h>
#include <conio.h>
int main()
{
srand(time(NULL));
int start, stop, amount;
system("chcp 1250 >nul");
printf("Welcome to random number generator!\n");
printf("\nWhat range? \nFrom: "); scanf("%i", &start);
printf("To: "); scanf("%i", &stop);
printf("\nHow many numbers?: "); scanf("%i", &amount);
int number[amount];
for(int i=0; i<amount; i++)
{
number[i] = rand() % ((stop+1)-start) + start;
for(int j=i; j>-1; j--)
{
if(number[i]==number[j])
{
number[i] = rand() % ((stop+1)-start) + start;
}
}
printf("\n%i generated number: %i", i+1, number[i]);
Sleep(10);
}
getch();
}

Your "check for dupes" loop is incorrect. You might find a duplicate, but then you don't check if that re-generated number exists in the stuff you ALREADY tested.
e.g. consider an array like this. user asked for 5 numbers, range 1-10
number[0] = 5
number[1] = 6
number[2] = 2
number[3] = 8
Now you're working on number[4]. You generate 2... You scan the array backwards and find that 2 is a dupe. So you generate a new number... and generate 8. But you don't reset your j loop - you just keep working backwards, and never see that 8 was already in the array.
What you should have is something more like:
for(int j=i; j>-1; j--) {
if(number[i]==number[j]) {
number[i] = rand() % ((stop+1)-start) + start;
j = i; // RESET THE LOOP
}
}
And note that your code can easily produce an infinite loop. e.g. consider someone asking for numbers in a range 1-3, and generate 4 of them. 1,2,3,?. The condition can never be satisfied, because you can't have 1-3 without at least one repeat.

So, even if we assume that rand() is a perfect random number generator, the numbers would repeat.
Lets say you have to generate 100 numbers. Say your start = 1 and stop = 100.
you generate a first number from 1 to 100, then the second and so on.. The more numbers you've used so far, the easier it is to get a duplicate.
Then you find a duplicate with that inner for-loop. You generate a new number for
number[i], but you have no guarantee that this number's unique. You may as well end up
setting number[i] to another duplicate.
If you want your code to work, you have to keep changing number[i] as long as it has a duplicate.
That's regarding the bug in your code.
On the other hand, this code is horribly inefficient, so you should consider optimising it if you plan on running this procedure often.

Related

Inputing a value and instead of keeping that information in a array, it changes another var

I made a program and then it didn't worked. As in the other post someone advised me to trying to debug my programs, I learned it and debugged this one. Probably it has some basic errors of writting but that's because I've changed a lot of thing recently to understand what's happening. In third time when I input a value on screen on that loop, it changes my var "i" to that value instead of keeping that number in my array "grade".
First I tried to make it all in one loop, the first one, but as always it didn't help much, and then i wrote the code by this manner as you'll see
#include <stdio.h>
#include <stdlib.h>
int main()
{
int j=0,sum=0,i=0;
int grade[]={0};
for(;j<100;j++){
printf("Type a grade:\t");
scanf("%d",&grade[j]);
if(grade[j]<10||grade[j]>20){
break;
}
}
for(;i<j;i++){
sum=sum+grade[i];
}
float average=sum/j;
printf("The average is: %.2f\n",average);
system("pause");
return 0;
}
The exercicise says that you need to read "x" grades from a student and it needs to be between 10 and 20, if the number is out of this range it stops the loop.After I just need to calculate the average os these grades.I don't really know if my var average is being calculated correctly, cause I didn't could reach over there because of my problem. If you input 11, 12 and 13 it should give to a sum of 36, but gaves me 26, i don't know how.
Erik, you should define your array in a coherent way. To allow the necessary number of elements, try defining a numeric constant. You could use it for both define the number of iterations of your cycle and the size of your grade array. You can also avoid a new cycle to calculate the sum of the array, you can do this operation while reading the grades, using only one for loop. Try this way:
#include <stdio.h>
#include <stdlib.h>
#define MAX_GRADES 100
int main()
{
int j,sum=0,i;
float average;
int grade[MAX_GRADES];
for(j = 0 ; j < MAX_GRADES; j++)
{
printf("Type a grade:\t");
scanf("%d",&i);
if ( (i<10) || (i>20) )
break;
grade[j] = i;
sum += i;
}
if (j > 0)
average = (float)sum/j;
else
average = 0;
printf("The average is: %d, %d, %.2f\n",sum, j, average);
system("pause");
return 0;
}

New way to generet random numbers but

I am trying to find 6 number one is from 10-100 and the other five numbers are between 1-10
the articles that I read about generating new numbers was somehow complex for me to apply so I made a new simple way by obtaining a series of repetitions of these numbers and put them in two-dimensional array after that I used rand() as index to the first array parameter so I could find the random numbers but I have a problem ..I want to put the generated numbers in array because I want to use them later.
I'll be thankful if you explain in a simple way
include<sys/time.h>
#include<stdio.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#include<ctime>
#define max 1000
int main()
{
int o, gr1num1[max][1] ,n=6,q[max] ,i = 0, gr2num5[max][5];
while(1)
{
i++;
gr2num5[i][4] = rand() % 10+1 ;
if(i == 1000)
break;
}
if (gr2num5 [i][4]!=0)
srand(time(NULL));
printf("\ngroup 2 numbers %d ",gr2num5 [rand()%500][4]);
printf("\ngroup 2 numbers %d ",gr2num5 [rand()%500][4]);
printf("\ngroup 2 numbers %d ",gr2num5 [rand()%500][4]);
printf("\ngroup 2 numbers %d ",gr2num5 [rand()%500][4]);
printf("\ngroup 2 numbers %d ",gr2num5 [rand()%500][4]);
printf(" \n\n\n /// %d /// ",o);
while(1)
{
i++;
gr1num1[i][1] = rand() % 100+10;
if(i == 1000)
break;
}
printf("group 1 number %d",gr1num1 [rand()%500][1]);
}
First off you should go back and re-read your book on C for how to do loops as whilst syntactically correct, the way you're using those while loops isn't right.
This is how your first while loop should look. The increment of i happens at the end of the loop since the index of arrays starts at 0.
i=0;
while(i<max)
{
gr2num5[i][4]= rand() % 10+1 ;
i++;
}
But really it would be better done as a for loop like this as it wraps up the initialisation, conditional and incrementation all in one neat package. The first part - the initialisation - is important as for your second while loop, your value of i is still 1000 as you don't reset it to 0.
for(i=0;i<max;i++)
{
gr2num5[i][4]= rand() % 10+1 ;
}
But you're after 5 values, so you need to nest two loops within each other to populate the gr2num5 array like this.
for(i=0;i<max;i++)
{
for(j=0;j<5;j++)
{
gr2num5[i][j]=rand() % 10+1 ;
}
}
(NB: you'll define j at the top along side i)

Printing non duplicate in C array

I was working on a program for my intro to C class (xtra credit assignment) and can't figure out how to discard duplicates numbers on an array. The problem asks to only print non duplicates; so I able to print the first number, compare the following and print if different, I discard the next if a duplicate, but the thing is I've only figured out how to compare the one number it following one, I figured I could do another for loop inside the for loop, but I'm getting super confused and just can't figure it out. I've already submitted my code last week, I've just been working on this trying to figure it out for myself so any help/guidance would be greatly appreciated.
"EDIT: Here's the problem: Use a single-subscripted array to solve the following problem. Read in 20 numbers, each of which is between 10 and 100, inclusive. As each number is read, print it only if it's not a duplicate of a number already read. Provide for the worst case in which all 20 numbers are different. Use the smallest possible array to solve this problem"
Thanks in advance, and any advice on how I'm writing my program would also be appreciated as I'm a total noob, and trying to be a good programmer with as little bad habits as possible.
#include <stdio.h>
#include <stdlib.h>
#define AS 20
void findDuplicate (int af[], int fAS);
int main(){
int a[AS], i , j, k;
int last = 0;
printf("Enter %d numbers between 10 and 100:\n", AS);
for (i = 0; i < AS; i++){
scanf("%d",&a[i] );
if (a[i] >= 10 && a[i] <= 100 ){
continue;
} else {
printf("You must enter values between 10 - 100\n");
i = i -1;
}
}
findDuplicate(a, AS);
system ("pause");
return 0;
}
void findDuplicate (int af[], int fAS){
int c;
printf("You entered ");
for (c=0; c < fAS; c++){
if (af[c] != af[c+1]){
printf("%d ", af[c]);
}
continue;
}
printf("\n");
}
You should first define an Array which can save as many variables as you want ..
Lets say you are comparing for 10-100 which means 91 possible different digits.
so , define array with the size of 91. and then do the scanning in for loop for 91 times to find out if you have that variable entered previously. If not then save it and display it ,else discard it.

Adding Numbers Generated By Random Number Generator in C

before I ask my question I would like to point out that I did look for the answers already, and I didn't find what I was looking for.
Please bear in mind that I am a beginner in terms of programming, so please don't assume that I know everything there is to know.
Right, to the question.
My question is : How do I add together numbers that are created by random number generator ? The difficulty that I have is the fact that the number of randomly generated numbers could be different every time the program is ran. To make it clearer, the amount of randomly generated numbers is dependent on the input from user, eg if the input is 9, the program will generate 9 random numbers. This makes it difficult for me to come up with the idea of how to add the random numbers together and display them.
Here is the source code from my program. I think it is important to mention that the random numbers change every time I run the program, which is how I want them to be ( I used srand() with time, and rand() ). Also, the problem that I have currently is that the program doubles the last randomly generated number instead of adding them all together.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int input;
scanf("%d", &input);
int i;
int roll;
int turn_total;
time_t t;
int sum;
srand((unsigned) time(&t)); // the seed for the random number generator based on the current time
for( i = 0; i < input; i++)
{
roll = (rand() % 6 + 1); // random number generator
sum = roll+roll; // only dubbling the last roll for some reason = /
printf("You Rolled : %d\n", roll);
}
printf("The Total Turn Score is : %d", sum);
}
Any help, ideas or clues would be greatly appreciated.
Yo need to initialize sum first also you are not adding properly.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
int input;
scanf("%d", &input);
int i;
int roll;
time_t t;
int sum = 0;
srand((unsigned) time(&t)); // the seed for the random number generator based on the current time
for( i = 0; i < input; i++)
{
roll = (rand() % 6 + 1); // random number generator
sum += roll; // only dubbling the last roll for some reason = /
printf("You Rolled : %d\n", roll);
}
printf("The Total Turn Score is : %d", sum);
}
Use
srand( ( unsigned int )time( NULL ) );
and initialize variable sum. For example
long long int sum = 0;
//...
sum += roll;
//...
printf( "The Total Turn Score is : %lld", sum );
Your program is doubling the number that was generated because that's what you tell it to do in this line:
sum = roll+roll;
Instead, you need to add the current roll to the current value of sum:
sum = sum + roll;
And you need to initialize sum to 0 so that you start by adding just the first roll.
Think about it like rolling a dice multiple times and writing down what it was each time. You roll it once and get a 3, so you write down 3. You roll it again and get a 6, so you add 6 to the previous roll to get 9. You roll again and get 2, so you add 2 to 9 and get 11, and so on. The variable sum is where you write down the new number after every roll, but you're adding to what you wrote down before.
The way you had it before, you were completely disregarding the previous rolls. rolls in the loop only refers to the latest roll that you performed, and since the loop ends at some point, sum will be left as the sum of the last value of roll. This is why you were getting double the last number.
replace
sum = roll+roll
with
sum = roll+sum;

C prime factorization (loop failure?)

I've been looking into this simple piece of code for 1.5 hrs now and do not find the mistake. I start going crazy ;)
Could anyone of you with a fresh mind and view give me a little hint, where I might have the mistake in? (I am relatively new to C)
The problem is: The code works fine for most of the numbers I entered and tested, but accidentically I found a number that does not work: 3486118 (or 55777888 which is a multiple of it) It goes right for the first loop(s), but after factor 2 it becomes an endless loop.
Here is my code: (any help is greatly appreciated)
// Program calculates prime factors of entered number and returns them
#include <stdio.h>
int main() {
long int num, num_cp;
long int product=1;
/*prime number array up to 100.000*/
long int prime[] = {2, 3, **[...cut out MANY numbers...]** 99971, 99989, 99991};
printf("Please enter a positive integer:\n");
scanf("%li", &num);//55777888 or 3486118 not working... why?
//copy the entered number to keep the original for comparison with "product" and "break;" if equal
num_cp=num;
printf("prime factorization of %li:\n\n", num);
for (int i=0; i<sizeof(prime); i++) {
if (num_cp%prime[i]==0) {
num_cp/=prime[i];
product*=prime[i];
if (product==num) {
printf("%li\n\n", prime[i]);
break;
}
printf("%li*", prime[i]);
//If prime factor found but "product" is still not equal to "num" reset loop counter "i" to -1 (==0 in next loop)
i=-1;
}
}
printf("END");
return 0;
}
"I've been looking into this simple piece of code for 1.5 hrs now and do not find the mistake. I start going crazy ;)"
Don't. Leave it. Go away and eat a pizza. Veg out in front of your favourite movie. Have a shower. Aim for a new high-score on 2048 (or whatever). Your brain gets stuck in a rut and you are no longer seeing your code. You are only seeing what you think your code is.
When you get your brain out of the rut, then -- and only then -- go back and actually read the code you wrote. Not the code you think you wrote, but the code you actually wrote. Yes, they are different.
The prime factors of 55777888 are 2·2·2·2·2·1743059, where the last factor is too large to be contained in your list.
You can fix this in your code: When the product is equal to the product of the prime factors you have found, num_cp is 1. If num_cp is greater than one after you have exhausted your prime list, it is a factor of num. If num/num_cp is smaller than the largest prime you have checked, you can assume that the remaining value of num_cp is a prime. If it wasn't you'd have found more factors earlier.
You can fix this by adding an additional check after your main loop:
if (num_cp > 1) printf("%li\n\n", num_cp);
(If long int is a 64-bit number on your system, you're still not safe: The remaining factor might be made up of several numbers that are not in your array.)
Finally: Resetting the for loop counter so that the loop starts over isn't a good idea. It always starts from the beginning and re-checks primes that you have already checked. And it just isn't natural program flow, which makes it hard to read. A while loop instead of the inner if block would be more natural in my opinion.
Edit: To illustrate:
#include <stdio.h>
int main() {
long int num;
/* prime number array up to 100.000 */
long int prime[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
int nprime = sizeof(prime) / sizeof(*prime);
num = 55;
printf("%li == ", num);
for (int i = 0; i < nprime; i++) {
long int p = prime[i];
if (num <= 1) break;
while (num % p == 0) {
num /= prime[i];
printf("%li", p);
if (num > 1) printf(" * ");
}
}
if (num > 1) printf("%li", num);
printf("\n");
return 0;
}
Things to note:
Instead of resetting the main loop counter i, a while loop is used, which consumes all repetitions of the same factor. If a prime p doesn't divide the number, the while loop isn't entered, just like an if clause.
I've removed the copy of num and used num throughout, mainly to remove clutter. I've also removed the product. Your logic that all prime factors should multiply to the original number, is good. But it also works the other way round: After dividing the number by all primes, we are left with 1. And we have to divide the number anyways. By removing the product, we have to keep track of only one variable instead of two.
I've moved the break condition to the front, so we catch negative numbers and 0 early.
That said, your way to code isn't wrong, just maybe a bit unusual in places.

Resources