I have a program that looks something like this. i would like to run my if else query by probability.
int main() {
int probability = 70; //<-- 70% probability to run if statement
for (int i = 0; i < 5e5; i++){
if (???){
...
}
else {
...
}
}
return 0;
}
As #user3386109 pointed out, if(rand() % 100 < chance) is probably more then sufficient. As explained in the C FAQ, when the random number generated is not a multiple of 100, here, this method causes some numbers to appear more than others. If it falls on the range where it makes a difference, the easiest thing is to draw another number.
#include <stdio.h>
#include <stdlib.h> /* rand() */
#include <time.h> /* clock() */
/** http://c-faq.com/lib/randrange.html */
static int rand_0_99(void) {
unsigned int x = (RAND_MAX + 1u) / 100;
unsigned int y = x * 100;
unsigned int r;
do r = rand();
while(r >= y);
return r / x;
}
int main(void) {
size_t i, cumulate = 0;
const size_t replicas = 1000000;
const int chance_100 = 70;
/* Seed the linear congruential generator with the time. */
srand((unsigned)clock());
for(i = 0; i < replicas; i++) {
const int decision = rand_0_99() < chance_100;
if(decision) cumulate++;
}
printf("P(r < %d/100) = %lu/%lu\n",
chance_100, (unsigned long)cumulate, (unsigned long)replicas);
return EXIT_SUCCESS;
}
This is overkill, but may be needed, especially when 100 is close to RAND_MAX.
Related
I need to multiply a number by 10 to the (x) power, depending on the exponent I may require.
I know there is a function, in the <math.h> library, but I was wondering if I could make my own function to achieve basically the same but only for 10, not any number. It´s for course homework, but since we haven´t been told about this library, I want to try to achieve it without said power() function.
Here's my code; it does compile, but I get some weird number instead of the intended 5000.
#include <cs50.h>
#include <stdio.h>
int ten_to_the(int n);
int main(void) {
int x = 50;
x *= ten_to_the(2);
printf("%.i\n", x);
}
int ten_to_the(int n) {
n = 1;
for (int i = 0; i < n; i++) {
n *= 10;
}
return n;
}
Because you multiple n by 10 on each iteration of the loop, i < n can never become true. In practice, n keeps getting bigger until it overflows and becomes negative.
Use another variable to keep track of the result separate from the number of iterations you need to calculate.
Instead of this:
int ten_to_the(int n)
{
n = 1;
for (int i = 0; i < n; i++)
{
n *= 10;
}
return n;
}
This:
int ten_to_the(int n)
{
int result = 1;
for (int i = 0; i < n; i++)
{
result *= 10;
}
return result;
}
I can get the random numbers into an array but I can't figure out how to check to make sure that they aren't repeating. I print out the code but there are no numbers in the array (prints out nothing).
//puts random numbers into an array
i = 0, j = 0;
srand(time(NULL));
for (i = 0; i < arrSize; i++)
{
randArr[i] = randNums(1,50);
}
i = 0;
for(i = 0; i < arrSize; i++)
{
printf("%d ", randArr[i]);
}
printf("\n\n");
//checks to make sure there are no duplicates
i = 0, j = 0, k = 0, temp = 0;
for (i = 0; i < arrSize; i++)
{
for (j = 1; j <= arrSize;)
{
if (randArr[j] == randArr[i])
{
for (k = j; k <= arrSize; k++)
{
temp = randNums(1,50);
randArr[k + 1] = temp;
}
arrSize--;
}
else
j++;
}
}
//generates random numbers between the inputed max and min
int randNums(int min, int max)
{
int result = 0, low = 0, high = 0;
if (min < max)
{
low = min;
high = max + 1;
}
else
{
low = max + 1;
high = min;
}
result = (rand() % (high - low)) + low;
return (result);
}
Beware! There are many different solutions to this problem and they all have one or another downside. If I was to quickly implement it, I would go for something like this (without too much C-magic going on):
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE (30)
#define RAND_MIN (1)
#define RAND_MAX (50)
static int randNums(int min, int max) {
// ...
}
int main(void) {
(void) srand(time(NULL));
int arr[SIZE];
int used = 0;
while (used < SIZE) {
int num = randNums(RAND_MIN, RAND_MAX);
bool exists = false;
for (int i = 0; i < used; ++i) {
if (arr[i] == num)
exists = true;
}
if (exists == false)
arr[used++] = num;
}
for (int i = 0; i < SIZE; ++i)
(void) printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
I hope it helps a bit :)
Like this answer, you can do rejection sampling, but the uniform distribution of a fixed number of samples is perfect for a very simple hash set. (Though the asymptotic runtime might be irrelevant for n=6.)
#include <stdlib.h> /* (s)rand */
#include <stdio.h> /* printf */
#include <time.h> /* clock */
#include <assert.h> /* assert */
/* Double-pointers are confusing. */
struct Reference { int *ref; };
/* Simple fixed hash set. */
static struct Reference bins[256];
static int nums[6];
static const size_t no_bins = sizeof bins / sizeof *bins,
no_nums = sizeof nums / sizeof *nums;
static size_t count_num;
/* Uniformly distributed numbers are great for hashing, but possibly clump
together under linear probing. */
static size_t hash(const int n) { return ((size_t)n * 21) % no_bins; }
/* Linear probing. */
static struct Reference *probe(const int n) {
size_t bin_index;
struct Reference *bin;
assert(sizeof bins > sizeof nums);
for(bin_index = hash(n); bin = bins + bin_index,
bin->ref && *bin->ref != n; bin_index = (bin_index + 1) % no_bins);
return bin;
}
/* Return whether it's a new value. */
static int put_in_set(const int n) {
struct Reference *bin = probe(n);
int *num;
assert(count_num < no_nums);
if(bin->ref) return 0; /* Already in hash. */
num = nums + count_num++;
*num = n;
bin->ref = num;
return 1;
}
/* http://c-faq.com/lib/randrange.html */
static int rand_range(const unsigned n) {
unsigned int x = (RAND_MAX + 1u) / n;
unsigned int y = x * n;
unsigned int r;
assert(n > 0);
do {
r = rand();
} while(r >= y);
return r / x;
}
/* Generates random numbers between the inputed max and min without
repetition; [min, max] inclusive. */
static int unique_uniform(const int min, const int max) {
int n;
assert(min <= max && (size_t)(max - min) >= count_num);
do { n = rand_range(max - min + 1) + min; } while(!put_in_set(n));
return n;
}
int main(void) {
int n = 6;
srand((int)clock()), rand(); /* My computer always picks the same first? */
while(n--) { printf("%d\n", unique_uniform(1, 50)); }
return EXIT_SUCCESS;
}
However, if the numbers are densely packed, (eg, unique_uniform(1, 6),) it's going to reject a lot of numbers. Another solution is to take a Poisson distributed numbers as a running sum, (recurrence T(n+1)=T(n)+\mu_{n+1},) where the expected value is the range of numbers divided by the total samples, then take a random permutation.
I'm trying to work through pset1 in Harvard's CS50 class through edX/ iTunesU and I'm attempting to program Luhn's algorithm. The below code is very incomplete but I wanted to know how to use pow() within a for loop and utilizing i within pow(). Presumably, there is another way to program Luhn's algorithm without using pow(), but exploring this method has brought this question to my attention. Any suggestions?
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
long long c = 1234123412341234;
long long temp_c = c;
long long temp_c_one = c;
long long c_one_x = 0;
int count = 0;
while (temp_c > 0LL) {
temp_c = temp_c / 10LL;
count++;
}
for (int i = 0; i < count; i++) {
c_one_x = (temp_c_one % (pow(10, (i + 1))) / (pow(10, i));
count--;
}
}
You can avoid the use of pow by having a counter which you multiply by 10 every loop iteration.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
long long c = 1234123412341234;
long long temp_c = c;
long long temp_c_one = c;
long long c_one_x = 0;
long long pwr = 1; // 10^0 = 1
int count = 0;
while (temp_c > 0LL) {
temp_c = temp_c / 10LL;
count++;
}
// TODO: Don't think you should decrement count in this loop
for (int i = 0; i < count; i++) {
c_one_x = (temp_c_one % (pwr * 10)) / pwr;
count--;
pwr *= 10;
}
}
However, I'm not convinced you have produced a good Luhns algorithm implementation, so my suggestion is:
// Better Luhn's algorithm
int luhn( long long cc) {
unsigned long check = 0;
unsigned int digit;
for (int i = 0; cc > 0; i++) {
digit = cc % 10;
// double every second digit
if (i % 2) {
digit *= 2;
digit = (digit >= 10) ? (digit + 1) % 10 : digit;
}
check += digit;
cc = cc/10; // next CC digit.
}
return check;
}
int main (void) {
long long c = 1234123412341234;
print "Result is : %d", luhn(c));
}
The code runs just fine but instead of using "for loop" to iterate upto 200000 , I think there can be a better alternative and I am having trouble finding it. I need help to optimise this solution.The time taken by this solution currently is 56ms.
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
int isPrime(long long int number)
{
int i;
for (i=2; i*i<=number; i++) {
if (number % i == 0) return 0;
}
return 1;
}
int returnNPrime(int N)
{
int counter = 0;
int i ;
if(N == 1) return 2;
for(i=3;i<200000;i+=2)
{
if(isPrime(i))
{
counter++;
if(counter == (N-1))
return i;
}
}
return 0;
}
int main(int argc, char *argv[])
{
printf("%d",returnNPrime(10001));
return 0;
}
Don't put an arbitrary stop condition. You know that the list of primes is infinite and that the loop will eventually stop. Write it like this:
int returnNPrime (int N)
{
int counter = 0;
int i;
if (N == 1) return 2;
for (i = 3; ; i += 2)
{
if (isPrime(i))
{
counter++;
if (counter == (N - 1))
return i;
}
}
}
That being said, this solution is inefficient because you don't store previously found primes.
Try something like this:
#include <stdio.h>
#include <stdbool.h>
#define N 10001
int primes[N] = { 2, 3 };
int main ()
{
for (int n = 2; n < N; n++) {
for (int x = primes[n - 1] + 2; ; x += 2) {
bool prime = true;
for (int i = 0; i < n; i++) {
int p = primes[i];
if (p * p > x) {
break;
}
if (x % p == 0) {
prime = false;
break;
}
}
if (prime) {
primes[n] = x;
break;
}
}
}
printf ("%d\n", primes[N - 1]);
}
Read this paper http://cr.yp.to/bib/1996/deleglise.pdf which describes how to count the number of primes <= N in O (n^(2/3)) or so and implement the algorithm. It's substantially faster than the Eratosthenes sieve, because it doesn't actually find any primes but just counts how many there are.
Make an educated guess how large the n-th prime would be. Say the guess is x. Use the algorithm above to find out how many primes <= x there are, then use a sieve if you are close enough, or use a better guess with the information you just found and try again. Total time O (n^(2/3)).
With some decent hardware and a lot of patience this will let you find solutions up to n = 10^22 or so.
OP's method consumes a lot of time with as it does not take advantage that there is no need to determine the remainder if i is not a prime.
for (i=2; i*i<=number; i++) {
if (number % i == 0) return 0;
The Sieve_of_Eratosthenes is likely faster yet is a dramatic change from OP's code.
Suspect this code is still too slow for OP.
The follows adjust OP's code by only attempting to test against previously found primes. Also it uses pcandidate / plist[index] as part of a terminating condition. Optimized compilers often can provide this at a small cost once pcandidate % plist[index] is computed.
bool prime_test(const unsigned long *plist, unsigned long long pcandidate) {
if (pcandidate <= 2) return pcandidate == 2;
for (size_t index = 0; ; index++) {
unsigned long long remainder = pcandidate % plist[index];
if (remainder == 0) return false;
unsigned long long quotient = pcandidate / plist[index];
if (quotient < plist[index]) return true;
}
assert(0);
return true;
}
unsigned long long prime_nth(size_t n) {
unsigned long plist[n+1];
plist[0] = 2;
unsigned long long pcandidate = plist[0];
for (size_t index = 0; index <= n; index++) {
while (!prime_test(plist, pcandidate)) pcandidate++;
plist[index] = (unsigned long) pcandidate;
pcandidate++;
}
return plist[n];
}
A classic simplification involves only seeking new primes amongst odd numbers. Also change all math to unsigned. Left for OP.
I've created a program that use rand() to generate repeated number in C.
However the repeated number doesn't follow Central Limit Theorem
Can anyone solve this rand() bug problem or is there an alternative other than using rand() C library to generate better random number?
Here's the screen shot:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define TOTAL_THROW 10000000
typedef enum _COINTOSS {
UNDEFINED = 0,
HEAD = 1,
TAIL = 2
} COINTOSS;
COINTOSS toss_coin () {
int x = rand() % 2;
if (x == 0) return HEAD;
else if (x == 1) return TAIL;
}
void main () {
int x, i, j, v1 = 0, v2 = 200, total = 0;
int head_range[25] = {0};
int tail_range[25] = {0};
int no_range = 0;
int count = 0;
int repeated = 0;
COINTOSS previos_toss = UNDEFINED;
COINTOSS current_toss;
srand(time(NULL));
for (i=0; i<TOTAL_THROW; i++) {
current_toss = toss_coin(); // current toss
if (previos_toss == current_toss) {
count++;
} else {
if (current_toss == HEAD) head_range[count] += 1;
else if (current_toss == TAIL) tail_range[count] += 1;
previos_toss = current_toss;
count = 0;
}
}
for (i=24; i>=0; i--) {
printf("+%d = %d\n", i+1, head_range[i]);
}
puts("________________\n");
for (i=0; i<25; i++) {
printf("-%d = %d\n", i+1, tail_range[i]);
}
printf("\nTOTAL_THROW: %d\n", TOTAL_THROW);
printf("\nPress [ENTER] to exit. . .");
getchar();
}
Your problem is using modulus to get your random number into the required range, which uses the lower bits (it's a classic gotcha):
int x = rand() % 2;
The lower bits of rand() (a linear congruential generator (LCG)) are not as random as the high bits. This applies to all LCG's regardless of library or language.
For a range of [0..N), you should do something like this (which uses the high bits):
int r = rand() / ( RAND_MAX / N + 1 );