C - How to generate random numbers between 20 and 30? [duplicate] - c

This question already has answers here:
Generate random number in C within a range and a specific step
(2 answers)
How to use the rand function to make numbers in a specific range?
(4 answers)
Closed 5 years ago.
I've tried but it doesn't seem to give me the desired numbers. Here's my code so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, i;
printf("Value of n:\n");
scanf("%d", &n);
int t[n];
for(i=0; i<n; i++)
printf("%d ", rand()%20+30);
return 0;
}

printf("%d ", rand()%20+30);
generates random numbers between 30 and 50 (not included). You need
printf("%d ", rand()%10+20);
to generate between 20 and 30 (not included)
10 being the range, and 20 being the offset.
To include both end points (giving 11 possible values):
printf("%d ", rand()%11+20);

these are the expressions
number = 21 + rand() % 9 // for (20, 30)
number = 20 + rand() % 11 // for [20, 30]

Try rand()%10+20.
rand()%10 gives numbers between 0 and 9. Adding then 20 will give numbers between 20and 29.
For numbers between 20 and 30 (inclusive), use rand()%11+20.

To generate random number in range [A .. B], first take difference between numbers: D = B-A, then generate a random number in the range of [0..D] and add that to A:
unsigned myRand(unsigned fromA, unsigned toB)
{
if (fromA > toB) // check if fromA is
return myRand(toB, fromA);
int d = toB - fromA; // difference between numbers: D = B-A
int r = rand() % (d+1); // random number in the range of [0..D]
return r + fromA;
}
Or, you may just to it manually like this:
20 + (rand()%11)
Also, note that depending on implementation rand() returns values between 0 and RAND_MAX, so you won't be able to create random values large than RAND_MAX (which might be as small as 32767). In this cases you may combine multiple rand() calls to get large random numbers:
unsigned r = (rand() << 16) | rand();

Related

Odd Repetitions of Patterns When Using Rand()

Sample random password/string generator which generates 32 character strings. So, generates random numbers and keep those which are between 33 and 127 as these are the ASCII values which constitute valid text.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(0));
clock_t start = clock();
long long iterations = 0;
printf("Generating String...\n\n\t\" ");
for (int i = 0; i < 32; i++)
{
long long holder = 0;
while(holder < 33 || holder > 126)
{
holder = rand();
iterations++;
}
putchar(holder);
}
clock_t end = clock();
printf(" \"\n\n%.2lf s , %lld iterations & %lld avg\n",(double)(end - start)/CLOCKS_PER_SEC,iterations,iterations/32);
return 0;
}
Output repeats the string DEX&H1_(okd/YVf8;49=el%<j:#"T,NU in one form or another.
Some Outputs :
Generating String...
" DEX&H1_(okd/YVf8;49=el%<j:#"T,NU "
9.11 s , 893836506 iterations & 27932390 avg
Generating String...
" xq?!#O]tDEX&H1_(okd/YVf8;49=el%< "
7.59 s , 768749018 iterations & 24023406 avg
Generating String...
" MJxq?!#O]tDEX&H1_(okd/YVf8;49=el "
7.63 s , 748742990 iterations & 23398218 avg
Compiled with cc file.c -o file on Clang/macOS.
The way you're trying to get random numbers in a range is extremely inefficient. It's also most likely the source of the repetition you're seeing.
You should instead reduce the number returned to be within the desired range.
for (int i = 0; i < 32; i++)
{
int holder = (rand() % (126 - 33 + 1)) + 33;
putchar(holder);
}
The question of how to do it right has been addressed in another answer already. This is about the "*odd repetitions" part, which may not be so "odd" after all.
The following assumes a typical rand() implementation where:
all possible values are taken exactly once before rand() returns a previous value;
the next rand() value depends only on the previous value.
Under these assumptions, the 94 values between 34 = '\"' and 125 = '}' will be returned in a cycle, which will then repeat unchanged. Then the posted code will always return 32 consecutive characters from that cycle (including wraparound)
Suppose for example that the first run returns the 32-char string DEX&H1_(okd/YVf8;49=el%<j:#"T,NU. That means the 94-char cycle of the rand() generator includes that string followed by some permutation of the remaining 62 characters.
Then the next run will produce a 32-char string that overlaps the first one for at least, say, 16 characters iff the first eligible character has an index between [0, 15] or [78, 93]. The probability of that happening is 16 / 94 ≈ 17%. Conversely, the probability of not having such overlap is ≈ 83%, and the probability of no overlaps in the next 7 runs is 0.83^7 ≈ 0.27. So the chance of getting a "repetition" for the first string in the next 7 runs is ≈ 73% i.e. not too surprising.
[ EDIT ]   Also, it follows by a straight pigeonhole argument that any 6 runs will produce at least two strings that have a substring in common of length 16 or more.

C Program crashes at For Loop

I'm new to C programming (I have some very basic experience with programming via vb.NET), and I'm attempting to write a program for the Project Euler Problem #1.
https://projecteuler.net/problem=1
Algorithm
The challenge requires the programmer to find the sum of all multiples of 3 or 5 (inclusive) below 1000 (I used intInput to allow the user to enter an integer in place of 1000).
My current solution takes the input, and decrements it by 1 until (intInput - n) % 3 = 0, that is, until the next nearest multiple of 3 under the input integer is found.
The program then cycles through all integers from 1 to ((intInput - n) / 3), adding each integer to the sum of the previous integers, so long as the current integer is not a multiple of 5, in which case, it is skipped.
The resultant sum is then stored in intThreeMultiplier.
The above process is then repeated, using 5 in place of 3 to find the highest multiple of 5 under intInput, and then cycles through integers 1 to ((intInput - n) / 5), not skipping multiples of 3 this time, and stores the sum in intFiveMultiplier.
The output sum is then calculated via sum = (3 * intThreeMultiplier) + (5 * intFiveMultiplier).
The Problem
Whenever I compile and run my code, the user is allowed to input an integer, and then the program crashes. I have determined that the cause has something to do with the first For loop, but I can't figure out what it is.
I have commented out everything following the offending code fragment.
Source Code:
#include <stdio.h>
#include <stdlib.h>
void main()
{
int intInput = 0; /*Holds the target number (1000 in the challenge statement.)*/
int n = 0;
int count = 0;
int intThreeMultiplier = 1;
int intFiveMultiplier = 1;
printf("Please enter a positive integer.\n");
scanf("%d",intInput);
for( ; (((intInput - n) % 3) != 0) ; n++)
{}
/*for(; count <= ((intInput - n) / 3); count++)
{
if ((count % 5) != 0)
{
intThreeMultiplier += count;
}
}
count = 0;
for(n = 0 ; ((intInput - n) % 5) != 0 ; n++)
{}
for(; count <= ((intInput - n) / 5) ; count++)
{
intFiveMultiplier += count;
}
int sum = (3 * intThreeMultiplier) + (5 * intFiveMultiplier);
printf("The sume of all multiples of 3 or 5 (inclusively) under %d is %d.",intInput, sum);*/
}
This is my first time posting on StackOverflow, so I apologize in advance if I have broken any of the rules for asking questions, and would appreciate any feedback with respect to this.
In addition, I am extremely open to any suggestions regarding coding practices, or any rookie mistakes I've made with C.
Thanks!
scanf("%d",intInput);
might be
scanf("%d", &intInput); // note the ampersand
scanf need the address the variable where the content is to be stored. Why scanf must take the address of operator
For debugging only, print the input to verify that the input is accepted correctly, something like
printf("intInput = %d\n", intInput);
The first thing you need when you are inputting intInput you should use:
scanf("%d", &intInput);
Because scanf() need as an argument of a pointer to your variable. You are doing this by just putting the & sign before your int.
In addition I think that you should double check your algorithm, because you are summing up some numbers more than once. :)

Generating unique random numbers except from a specific one in C [duplicate]

This question already has answers here:
Unique (non-repeating) random numbers in O(1)?
(22 answers)
Closed 9 years ago.
I was wondering, how can I generate unique random numbers except from a specific one. For example, if I want to generate numbers in range 1 to 10 except from 3, the output should be something like this:
7 6 1 2 4 9 5 8 10
Shuffle the numbers 1 - 10 and remove 3.
It doesn't matter if you remove the 3 before or after shuffling.
Alternatively, shuffle the numbers 1 - 9 and relabel 3 as 10...
For shuffling without bias you can use for example the Fisher-Yates algorithm. http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Generate random number in the range 1..9 and add one if the number is greater than or equal to 3.
Generate a number. Check its value, if the number is 3 generate another one. If it isn't 3 then use it.
EDIT: Thinking before coffee is a terrible plan. If you want to get every number in the range in a random order then I agree with the others talking about shuffling lists. If however you want some random subset of the range I would store a list of forbidden values. Shuffling and only taking the first n numbers would also be suitable if the range isn't very large (e.g. not something like 0<x<INT_MAX).
Every time you generate a number check if the generated number is on the forbidden list and if it is, generate another number. Every time you generate a valid number you add it to the list to ensure generated numbers are unique. The list should also be initialised with your unwanted numbers (3 in the example given).
You may try like this:-
unsigned int
randomnumber(unsigned int min, unsigned int max)
{
double scaled = (double)rand()/RAND_MAX;
return (max - min +1)*scaled + min;
}
then later you can do this:-
x = randomnumber(1,10);
if (x==3)
{ x = x+1;}
or
if (x!=3)
{ printf("%d",x)}
This is my answer - returns random value in [min, max), except "except".
int myrand(int min, int max, int except) {
int rc;
do {
rc = min + rand() % (max - min);
} while(rc == except);
return rc;
}
This code will generate unique random numbers from minimum to maximum of a given range.
#include<stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int max_range, min_range, i = 0, rand_num;
srand((unsigned)time(NULL));
printf("Enter your maximum of range: ");
scanf("%d", &max_range);
printf("Enter your minimum of range: ");
scanf("%d", &min_range);
bool digit_seen[max_range + 1]; // VLAs For C99 only
for (int i = min_range; i <= max_range; i++)
digit_seen[i] = false;
for (;;)
{
rand_num = rand() % max_range + min_range;
if(rand_num !=3)
if(!digit_seen[rand_num])
{
printf("%d ", rand_num);
digit_seen[rand_num] = true;
i++;
}
if( i == (max_range - 1) )
exit(0);
}
return 0;
}

how to use rand() function with a range in C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C, how do I get a specific range of numbers from rand()?
Generate a random number within range?
I'm stuck on how to use the rand() function and include a range for that random number. I need a random number between 67.00 and 99.99 only to be printed.
This is what I have tried, but failed with...
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int x = rand();
if(x>=67.00)
if(x<=99.99)
printf("%d\n",x);
else
printf("not in range");
}
Instead of checking if the result is in the range, you can force the result to be in the range that you want:
int HIGH = 100;
int LOW = 67;
int rnd = LOW + (rand() % (HIGH-LOW));
The value of rnd is in the range between LOW and HIGH-1, inclusive.
If you do not want to force the number into range, change your condition to
if(x>=67.00 && x<=99.99)
Currently, the else belongs to the inner if, so the second printf does not happen when the number is less than 67.

Populate a 2D Array by a rule

How do I populate an array like this:
1 2 3 4
2 3 4 3
3 4 3 2
4 3 2 1
I need to find out a formula that determines the pattern of populating this array.
#include <stdio.h>
#define N 4
int main()
{
int i,j,arr[N][N];
int a=1;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
arr[j][i]=i+j+1;
}
for(i=0; i < N; i++)
for(j=0;j<N;j++)
printf("%2i ",arr[j][i]);
printf("\n");
return 0;
}
It prints out similarly to the desired array except that I need "3" at the end of the second row, and after that point, it goes reversed. Please, explain me how to do that.
Try this:
arr[j][i]=N-abs(i+j-(N-1));
abs() can be used any time you need a numerical sequence which is mirrored around some value. You just need to subtract a constant such that the value you want to mirror around is zero, take the absolute, and then re-adjust the output.
In your case (with N = 4) the (i+j) summation produces: 0,1,2,3,4,5,6. The middle value is N-1, as the largest value is 2 * (N-1).
Subtracting N-1 (3) gives: -3,-2,-1,0,1,2,3.
The abs() gives: 3,2,1,0,1,2,3.
If we subtract that from N (4) we get the desired 1,2,3,4,3,2,1 sequence.
arr[j][i]=(j * 3 + j/ 3 + b) % N + 1;

Resources