C++ Birthday Paradox Using a Boolean Function - c++

I have an assignment where I need to calculate the probability that two people share the same birthday for a given room size (in my case 50) over many trials (5000). I have to assign the birthdays randomly to the number of people in the room. The difference is I need to use a Boolean function to check the if the Birthdays are the same. I cannot figure why my outputs are off, but I believe it has something to do with two of my loops.
>
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
bool SameBirthday(int birthdays[], int numpeople);
const int MAX_PEOPLE = 50;
const double NUM_TRIALS = 5000.0;
const int DAYS_IN_YEAR = 365;
int main(void)
{
int numMatches = 0;
int people = 2;
int trial = 0;
int numpeople = 0;
int i = 0;
int birthdays[MAX_PEOPLE];
bool Match;
double Probability = 0;
srand(time(0));
for (people = 2; people <= MAX_PEOPLE; people++)
{
numMatches = 0;
for (trial = 0; trial < NUM_TRIALS; trial++)
{
for (i = 0; i < people; i++)
{
birthdays[i] = (rand() % 365 + 1);
numpeople = i;
}
if ((SameBirthday(birthdays, numpeople) == true))
{
numMatches++;
}
}
Probability = (numMatches / NUM_TRIALS);
cout << "For " << people << ", the probability of two birthdays is about " << Probability << endl;
}
}
bool SameBirthday(int birthdays[], int numpeople)
{
bool match = false;
int numberofmatches = 0;
//Use this function to attempt to search the giving array birthdays and count up number of times
//at least two people have matching birthdays for any given 1 trial
for (int SpaceOne = 0; SpaceOne < numpeople; SpaceOne++)
{
for (int SpaceTwo = SpaceOne + 1; SpaceTwo < numpeople; SpaceTwo++)
{
if (birthdays[SpaceTwo] == birthdays[SpaceOne])
{
return true;
}
}
}
return false;
}
I know that the code has errors in certain spots that was because I started trying different things, but any help would be appreciated.
EDIT- My only issue now is that for my output I have a zero for the probability of 2 people in the room have a birthday, which is not right. It seems like my outputs are like a person off, the probability of 2 people is shown as the probability for three people and so on.
EDIT(8-31-2015): I also forgot to mention that my Professor stated that my SameBirthday function needed the parameters: birthday[], and numpeople so I cannot use MAX_PEOPLE as a parameter. My professor also suggested using a triple nested for loop within the main body of the function. I believe what is making my output off by one for each person relates to the triple nested for loop, but I am unsure what would cause the issue.

Just do it like this:
bool SameBirthday(int birthdays[], int numPeople)
{
for(int x=0; x<numPeople; x++){
for(int y=0; y<numPeople; y++){
if(birthdays[x] == birthdays[y])
return true;
}
}
return false;
}
Your logic in your nested loop is wrong..
for (SpaceOne = 0; SpaceOne < numpeople - 1; SpaceOne++)
for (SpaceTwo = SpaceOne + 1; SpaceTwo < numpeople; SpaceTwo++)
Your inner loop is skipping n number of checks where n equals SpaceOne.
By the way, this is not C programming. You can declare variable within a for-loop.

I see two problems with the actual functionality. First, SameBirthday needs to return a value (false) when there is no birthday match. You can do that at the end of the function, after all the loops are done.
Second, you need to increment numMatches when you find a match.

To clarify issues from other parts of your coding. I think this is what your school wants.
int main(){
//All your variables
for(int x=0; x<NUM_TRIALS; x++){
for(int y=0; y< MAX_PEOPLE; y++){
birthdays[y] = (rand() % 365 + 1);
}
if(SameBirthday(birthdays, MAX_PEOPLE) == true)
numMatches ++;
}
Probability = ((double)numMatches / NUM_TRIALS);
cout << "For " << people << ", the probability of two birthdays is about "
<< Probability << endl;
}
NUM_TRIALS to generate 5000 datasets. Hence, you generate birthday for 50 students 5000 times. For each trial within a class of 50, you check whether there are 2 person with same birthday. If there is, numMatches + 1.
After 5000 trials, you get the probability.

Your other problem is that numpeople will always be the number of people minus 1. You don't actually need that variable at all. Your "people" variable is the correct number of people.

Related

Knight's tour problem compilation doesn't end

Could anyone point the flaw in the code?
The idea that I used is backtracking with recurrence and I would like to stick to this way of sloving the given problem. When the variable moves is <= 60 couple of answers are printed instantly though the program is still running. If moves = 61,62 it takes couple of minutes to print some solutions and if moves = 63 no solution is printed within 15 mins in both cases the program is still running.
Here is the code:
//checking on which move was the square visited
int board[8][8] = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
int x = 0;//x and y coordinate of the knight's placement
int y = 0;
//move knight by
int move_to[8][8] = {{1,2},{-1,-2},{-1,2},{1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
//how many moves have been done
int moves = 0;
void solve()
{
//printing one solution
if(moves==63)
{
for(int k = 0; k < 8; k++)
{
for(int n = 0; n < 8; n++)
cout << setw(2) << board[k][n] << " ";
cout << "\n";
}
cout << "--------------------\n";
return;
}
else
{
for(int i = 0; i < 8; i++)
{
//checking if knight is not leaving the board
if(x+move_to[i][0]<0 || x+move_to[i][0]>7 || y+move_to[i][1]<0 ||
y+move_to[i][1]>7 || board[x+move_to[i][0]][y+move_to[i][1]]>0)
continue;
//moving theknight
x+=move_to[i][0];
y+=move_to[i][1];
//increasing the moves count
moves++;
//marking the square to be visited
board[x][y] = moves+1;
//backtracking
solve();
board[x][y] = 0;
x-=move_to[i][0];
y-=move_to[i][1];
moves--;
}
}
}
int main()
{
solve();
return 0;
}
I remember this problem from study. I do not fix them but I change initial position then the first path is found faster (that is how I passed this lab ;P). It is normal because
the number of path is too big.
But you can:
choose from move_to in random order
use multiple threads
Other hand you can read about "Constraint Programming"

Value assignment into array c++

I'm trying to create a array of prime numbers done by calculation. As a project to learn coding. Ultimately to build my own math library so this is something I can add onto at a variety of levels as I learn to code c++.
The following is code that works great for printing prime numbers to the screen based on the search range, but my totalPrimes iterator is stuck at 1. So each time it places the last prime found in the PrimeNumbers[1] position.
Any advice would be awesome.
#include <iostream>
#include <array>
std::array<long, 10000000> PrimeNumbers={0};
void isPrime(long x);
int main() {
for (long i = 1; i < 10; i++) {
isPrime(i);
}
for(int h = 0; h < 10; h++) {
std::cout << "\nSecond Prime is : " << PrimeNumbers[h];
}
}
void isPrime(long x) {
int count(0), totalPrimes(0);
for (long a = 1; a < x; a++) {
if ((x % a) == 0) {
count += 1;
}
}
if (count == 1) {
++totalPrimes;
std::cout << '\n' << x << " is a Prime number";
PrimeNumbers[totalPrimes] = x;
}
}
You're initializing totalPrimes to 0 every time the function runs. You would need to have totalPrimes as a global variable, or better yet (because global variables can become problematic), set it equal to the first available member of PrimeNumbers before you do anything else in that function.
Keep track of a position along with your PrimeNumbers array.
size_t nLastPos=0;
...
for(size_t x = 0; 1000 > x; ++x)
{
if(isPrime(x))
{
PrimeNumbers[nLastPos++] = x;
}
}
for(size_t i = 0; nLastPos > n; ++n)
{/* print out number PrimeNumbers[n] */ }
It looks like you're having some trouble with variable scoping. The reason for your problem (as I noted in the comment) is that totalPrimes is local, so you're creating a new integer variable and setting it to 0 every time the function is called.
However, you've made PrimeNumbers global and are having the isPrime function modify it, which doesn't look like good practice.
All of this can be fixed with a little restructuring to make the code nicer:
#include <iostream>
#include <array>
bool isPrime(long x);
int main() {
std::array<long, 10000000> PrimeNumbers={0};
int totalPrimes = 0;
for (long i = 1; i < 10; i++) {
if (isPrime(i)) {
std::cout << '\n' << i << " is a Prime number";
PrimeNumbers[totalPrimes++] = i;
}
}
for(int h = 0; h < 10; h++) {
std::cout << h << " Prime is : " << PrimeNumbers[h] << std::endl;
}
}
bool isPrime(long x) {
int count(0);
for (long a = 1; a < x; a++) {
if ((x % a) == 0) {
count += 1;
}
}
return count == 1;
}
Your program can be re-structured little bit to make it easier to follow and debug.
Don't put things in isPrime other than the logic to decide whether a number is prime. Make sure it returns a bool. This will make the function a bit simpler and easier to debug.
Use the return value of isPrime in the calling function to perform other bookkeeping tasks.
The logic you have used to check whether a number is prime is incorrect. That needs to be fixed.
Here's an updated version of your posted code.
#include <iostream>
#include <array>
#include <cmath>
std::array<long, 10000000> PrimeNumbers={0};
bool isPrime(long x);
int main()
{
int totalPrimes = 0;
for (long i = 1; i < 10; i++)
{
if ( isPrime(i) )
{
std::cout << i << " is a Prime number" << std::endl;
PrimeNumbers[totalPrimes] = i;
++totalPrimes;
}
}
}
bool isPrime(long x) {
// 1, 2, and 3 are primes.
if ( x <= 3 )
{
return true;
}
// Even numbers are not primes.
if ( x % 2 == 0 )
{
return false;
}
// Check the rest.
long end = (long)std::sqrt(x);
for (long a = 3; a < end; a += 2) {
if ((x % a) == 0)
{
return false;
}
}
return true;
}
and its output:
1 is a Prime number
2 is a Prime number
3 is a Prime number
5 is a Prime number
7 is a Prime number
9 is a Prime number
Everybody is talking about how your totalPrimes variable is reset each time the function is called, and this is obviously true. You could return the value from the function and increment it from main, you could use global variables having the variable being defined outside of the function so that it's not reset each time inside the function or you could use
A static variable!
Take a look at this simple case. I have a function called up_two which increases the value of by two each time the function is called. The static variable int value has a memory of each time the function up_two() is called which increments value by two each time. If I were to use a just an integer it would always reset the value and have it be zero, which is what I initially defined it to be.
The advantage of using a static variable is that I can count how many times a function has been called, and I can keep my counter specific to a particular function.
#include <iostream>
using namespace std;
void up_two();
int main()
{
for(int i = 0; i < 10; i++)
{
up_two();
}
return 0;
}
void up_two()
{
static int value = 0;
cout << value << endl;
value += 2;
}
This program doesn't solve the particular problem that you want to solve, but if you figure out how the static variable is working, it should make your workflow easier.
The magic line here is this:
static int value = 0;
With it like this my program prints the following:
0
2
4
6
8
10
12
14
16
18
Without the static declaration, you just get 10 lines of zeroes
which is troublesome.
Hope that helps you optimize your program the way you want it to be.

Nested loop acting weird

EDIT: Posting everything, because it gets really weird.
using namespace std;
int main()
{
int doors = -1;
int jumper = 1;
bool isOpen[100];
string tf;
for(int i = 0 ; i < 100; i++){
isOpen[i] = false;
}
while(jumper < 100){
while(doors < 100){
if(isOpen[doors + jumper] == true){
isOpen[doors + jumper] = false;
}
else{
isOpen[doors + jumper] = true;
}
doors += jumper;
cout << doors << endl;
}
doors = -1;
jumper+=1;
}
for(int i = 0; i < 100; i++){
if(isOpen[i]){
tf = "open";
}
else{
tf = "closed.";
}
cout << "Door " << i << " is " << tf << endl;
}
return 0;
}
So I'm having a very odd problem with this piece of code.
It's supposed to go through an array of 100 items. 0 - 99 by ones then tows then threes, etc. However, after a = 10, it shoots up to 266.
Can anyone tell me why?
Edit:
This problem only happens when the for loop is commented out. When it is left in the code, it does the same thing, but it doesn't happen until 19.
If I comment out the "string tf;" as well, it continues to loop at 99.
This is all based on the doors count.
I'm unsure why either of these should be a factor to the loop that neither are connected to.
According to your description this is what you should do:
for(int adv = 1, i = 0; adv < 100;)
{
// i is array index (your b) -> use it somehow:
doSomething(arr[i]);
i += adv;
if(i >= 100)
{
i = 0;
adv++;
}
}
The (probable) reason you got weird behavior (including the 266 value) is that your code overruns the buffer. When b will be high enough (say 99), you'd write to isOpen[b + a] which will be 100 or higher (100 if a is 1, and that's just the first iteration, later iterations will go much further). If the compiler allocates isOpen before the ints you'll be overwriting them.

Project Euler #8 - C++ code failed to work

I know there are multiple topic regarding Project Euler #8. But I am using a different approach, no STL.
#include <iostream>
using namespace std;
int main(){
char str[] = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450";
int size = strlen(str);
int number = 1;
int max = 0;
int product = 0;
int lowerBound = 0;
int upperBound = 4;
for (int i = 0; i <= size/5; i++)
{
for (int j = lowerBound; j <= upperBound; j++)
{
number = number * str[j];
}
product = number;
number = 1;
lowerBound += 5;
upperBound += 5;
if (product > max)
{
max = product;
}
}
cout << "the largest product: " << max << endl;
return 0;
}
the answer is : 550386080, which is way too big and incorrect.
Please tell me what's wrong with my code. No advanced pointers or template technique, just control flow statement and some basic stuff.
Part of your problem is the expression
number = number * str[j];
The str[j] is an ASCII character and you are incorrectly assuming it's a numeric value in the range 0..9. A cheap way to convert a single numeric character to a number would be to say
number = number * (str[j] - '0');
That gets you closer to the correct answer but there is another problem. You are testing each index range like [0..4], [5..9], [10..14], [15..19], etc. You should instead be testing indices [0..4], [1..5], [2..6], [3..7], etc. I'll leave that for you to correct.

Creating a mathematical expression from nested loops

Can anyone show me how to create a mathematical expression for the number of time the statement total++; will run in the following code?
I understand that the 'i loop' will iterate n/P times and I know that total++; will run a total of 'i loop iterations' * 'j loop iterations'. But I don't know how to get a mathematical expression from this that is in terms of n and P.
#include <iostream>
using namespace std;
int total = 0;
int n = 20;
int P = 2;
int id = 1;
int test = 0;
int main()
{
for (int i = id*n/P; i < ((1+id)*n/P); i++)
{
cout << i << endl;
test++;
for (int j = 1; j <= i-1; j++) {
total++;
}
}
cout << test << endl;
cout << total;
return 0;
}
Look at the sum of the integers.
The inner loop runs i times, for each of a series of integer values of i, starting at one value and running to the other. If you have the sum of the integers from 1 to the first value, and the sum of the integers from 1 to the other, the difference is your answer.
The sum of the integers from 1 to n is a formula worth learning.