Eat. Sleep. Code: The Computer Programming Thread, Ver. 010

This is awesome that we have this. Im taking web programming and I definitely could use some help.

Java and efficient donā€™t go hand in hand, haha.

When I was learning, we started with C++ and then we branched out from there. Today you learn Java first. Itā€™s not bad, because Java holds your hand way more and you can do more interesting projects easier, and the main problem is people drop the major before doing anything worthwhile. But a lot of people who start with Java have a really hard time to when it comes to learning Pointers and stuff.

But yeah, I have a job programming, everything from C++ (my main thing) to Java/Flash/Flex based web apps

Iā€™ll be able to help out with this, Iā€™m proficient with PHP, jQuery, and Javascript.

Yeah sorry about that Wily, I was just messing around while listening to my Physics professor preach at the time so sorry if I screwed it up. And if youā€™re curious, Iā€™m majoring Electrical Engineering major and they told me this class was necessary so I guess Iā€™ll be taking more CP in the upcoming semesters as well.

I redid the program from scratch somewhat using Wilyā€™s program for reference and got


/*returns 1 if any people share a birthday*/
int party(numPeople)
{
  //generate birthdays
  int i, j, birthday[numPeople];
  for(i = 0; i < numPeople; i++);
  {
    birthday* = rand() % 365; /*ignore leap year, gives us a number between 0 and 365 to represent the birthday*/
  }
  for(i = 0; i < numPeople; i++);
  {
  //double loop, this checks each person against each other person in the most straightforward way possible
    for(j = i + 1; j < numPeople; j++);
    {
        if(birthday* == birthday[j]) //true if they share a birthday
          return 1; //we can return 1, 2 people shared a birthday
    }
  }
  return 0; //this only ever gets here if there were no matches
}
int main()
{
int numPeople, numTrials, currentTrial, nPartyResult, pSuccess;
int success = 0;
srand(time()); /*this seeds the random number generator based on the current millisecond*/

printf("Enter the number of guests: ");
scanf("%d", &numPeople);
printf("Enter the number of parties: ");
scanf("%d", &numTrials);

for(currentTrial = 0; currentTrial < numTrials; currentTrial++);
{
  int nPartyResult = party(numPeople);
  if(nPartyResult == 1)
    success++;
  }
  (float)pSuccess == success / (float)numTrials * 100;
  //output the result
  printf("The probability that two guests have the same birthday is %0.2%%
",
pSuccess);
return 0;
}

And the output


Enter the number of guests: 30
Enter the number of parties: 10000
The probability that two guests have the same birthday is 0.00%

Itā€™s nice that it runs in the first place but the 0.00% is weird and Iā€™m currently looking into that right now.

And I notice you like to use cout in place for printf, and cin for scanf, Iā€™m assuming thatā€™s C++?

I always would write:
%0.2f for a float number

ā€œis %0.2f
ā€, pSuccess)

Otherwise, check to make sure the math you use to compute it doesnā€™t truncate it to an integer. If itā€™s less than one (like all percentages), then a truncation to integer would make it zero.

EE: Youā€™ll get a lot of math, but itā€™s very possible you can get a job where having both the mathematical and practical understanding of software will help a lot. For instance you might use Verliog to describe an asynch or FPGA youā€™ll need to do something. (or System C, e, or any other number of circuit design softwares I donā€™t know about). I was only dabbling in EE as a CS and Control Systems undergrad/grad so I donā€™t know much, but I do know that we know lots of similar maths.

Anyways all Iā€™m saying is, trust what you were told, because there is a good chance they are foreseeing a common practical purpose to you studying this.

cin and cout are C++ ā€˜replacementsā€™ for fscanf and fprintf. If you delve deeper into C++ and STL, you can see the differences by using cin and cout, but if you use basic C data structures, you will see very minor differences and in fact may find fprintf to use less characters of code.

There are reasons for cin and cout, but the thing is, right after the first C++ standard was made, they updated C at C-99 and the problems in C went away. So really, you end up only using cin/cout if you prefer or you want to use C++ data structures.

How do I start? Iā€™ve always wanted to learn but have no idea where to look.

You start by finding something that would keep you motivated to learn how to do it.

Learning how to program a processor is a matter of studying, but you need motivation, you need to be able to break it down step by step, what you want a computer to do for you. If you can break it down into small pieces, you can figure it out at your leisure.

For instance, spreadsheet is a fine way to learn how to use a computer to your advantage.
What about scientific computing? What if youā€™re into some science and you want to do data crunching or modeling, you can use either a spreadsheet program or maybe a scientific computing platform such as Matlab or using Spyder python or Sage. Matlab is not free, but Spyder and Sage are.
Or maybe you want to make games. I have very little experience in platforms that would help people make games, but they exist. Even a custom map for Warcraft/Starcraft can be a very complicated piece of software, eg DotA.

@ MCP

I see what you mean about it being truncated, so I tried using float in order to get an actual decimal number when dividing ā€˜successā€™ with ā€˜numPartiesā€™ but I still get 0.00%

imo best way to learn is hands on so I wouldnā€™t be discouraged if you donā€™t have formal education. pick an interesting project and figure things out line by line

ā€¦damnit I laughed out loud at that, and I wish I hadnā€™t. I hate you for that but if I ever meet you at evo Iā€™ll have to buy you a beer.

I totally agree with this. I really think that it is better to learn something hard first, but having taught programming at points in my career, a lot of students do get discouraged by how overwhelming C++ can be at the start, especially for people who arenā€™t used to thinking like that. I really canā€™t see java as a language that Iā€™ll ever use for anything real, but it is not a bad teaching language for gauging interest. Python on the other hand is terrible. Seriously, I hate it so much. Hate hate hate. Just throwing that our there.

Iā€™ve never used the scripting languages for anything important (Python, Ruby, Lua) but I can totally see their appeal to people using them to get stuff done.

Modify your output so you can see all the variables and find out if its a truncation problem, or a logic problem. I actually see a big problem with your code that you will probably figure out when doing this that is causing you to see 0%. Hint: Itā€™s truncation

Yeah that sounds like a nifty technique to use, thanks for suggesting it!

My modified code:



#include <stdio.h>
#include <stdlib.h>
int party(int numGuests);
main()
{
int numGuests, numParties, currentTrial, nPartyResult;
int success=0; 
float percent;
srand(time());

printf("Enter the number of guests: ");
scanf("%d", &numGuests);
printf("Enter the number of parties: ");
scanf("%d", &numParties);

for(currentTrial = 0; currentTrial < numParties; currentTrial++);
{
  int nPartyResult = party(numGuests);
  if(nPartyResult == 1)
    success++;
  }
  percent = (float)success / numParties * 100;
  printf("%.2f%%
", percent);           
     return 0;  
} 
int party(int numGuests)
{
  int i, j, birthday[numGuests];  
  for(i = 0; i < numGuests; i++);
  {
    birthday* = rand() % 365;
  }
    for(i = 0; i < numGuests; i++);
    {
    for(j = i + 1; j < numGuests; j++);
    {
       if(birthday* == birthday[j]) //true if they share a birthday
          return 1; //we can return 1, 2 people shared a birthday
    }
  }
  return 0; //this only ever gets here if there were no matches
}

Anyway for the guests and parties variables, I get whatever numbers I type in for them no problem. For success however, it keeps reading 0, which leads me to believe that thereā€™s something wrong with the 2nd half of the program below the ā€œint party(int numGuests)ā€ if success isnā€™t incrementing.

Python is actually pretty badass.

Does your code actually compile for you? I get errors trying to compile that, besides just the missing includes, I get an error on the birthday[numGuests] line. If that really works in your compiler Iā€™m impressed. I just hardcoded it to 365 to get it to compile; and what Iā€™d do is if numGuests > 365 Iā€™d just return true since itā€™s guaranteed to have a matching birthday.

Anyhow, I debugged and stepped through your code to find out whatā€™s going on, and itā€™s not a truncation error since you fixed up the result going into an int by changing it to a float, which is good. You double declared nPartyResult too, but that wasnā€™t your bug. You have a fundamental syntax error on each for loop you have which is breaking your program.

For loops should be declared like this:



for(int i = 0; i < 100; i++)
{
  //code goes here
}


But what youā€™ve actually done is this



for(int i = 0; i < 100; i++);
{
  //code goes here
}


[S]Emphasis on the semicolon is mine[/S] (damn code blocks remove formatting!) You have an extra semicolon in your for loop declaration. This is valid C++ Syntax, but what happens is not what youā€™d expect. What happens is that the for loop is declared with an empty body, so it runs through the loop X number of times without ever hitting the code in your brackets; once itā€™s done, then it moves onto the code in the brackets (while C++ syntax allows you to put brackets without a matching loop is beyond me, but it does).

So basically, your loops never work properly. Your gut feeling about the function not working properly is correct, but also the loop that calls the function isnā€™t correct either. So you get into your function, scroll through all the birthdays, only assign a random number to the last slot of the array, then increment j to i + 1, and since thatā€™s already greater than numGuests, you bail out and always return 0.

Simply removing the extra semicolons from your for loop syntax will fix all your problems!

I actually was a Computer Science major, but I had to take some other classes much like you in other, related fields; namely Electrical Engineering and Computer Engineering. Learning to make logic circuits, processor programming and understanding, verilog and all that stuff was really awesome. I felt it really complemented my education in computer science to understand exactly how it worked behind the scenes. I had a project where we had to take a basic CPU design and extend it by adding new functions built into the CPU, diagram what logic changes we were adding to the board, put the function calls and everything down into a huge folder binder that was over 100 pages. A lot of work, but I still remember how awesome that was, adding encryption and decryption logic to a CPU. Even if it wasnā€™t my major, it was a lot of fun and very interesting.

However, EE was not for me. I still to this day donā€™t understand resistance, voltages, how to calculate all that stuff when looking at a diagram. I struggled through the class with 30 other computer science majors, with a teacher who didnā€™t care whatsoever about teaching us (he was used to people who knew what they were doing) and passed with like a 50% with a B because I Was that ahead of the curve. Terrible times.

So I understand the pain of having to work outside your comfort zone. Not sure if this programming stuff is fun and interesting, or tedious and a roadblock to a degree for you.

Just reading back through a little bit, on the declaring dynamic arrays, you can but you donā€™t do it like a normal array, and you can do it without malloc.

int * foo = new int[numberOfInts];

Something to keep in mind with this and the malloc method is that you are not creating a local you are actually reserving the memory so you have to manually delete it otherwise youā€™ll leak memory.
Also

Loop(stuff);

Is super irritating to track down and EVERYONE does it early on in their programming career.

Iā€™m also a proffessional programmer so iā€™ll try and help out when I can.

Wow, I never wouldā€™ve thought about the semicolons thanks! I never realized how different the syntax in C++ is, for example, I notice how you put ā€˜int variableā€™ in your programs, wheras in C, I canā€™t do that, I have to declare the variables first and when theyā€™re used, the only thing I type in is the letter or word of a specific variable.

Anyway my output now reads



Enter the number of guests: 30
Enter the number of parties: 10000
The probability that two guests have the same birthday is 70.84%

Enter the number of guests: 30
Enter the number of parties: 1000000
The probability that two guests have the same birthday is 70.60%

Enter the number of guests: 40
Enter the number of parties: 100000
The probability that two guests have the same birthday is 89.18%

Iā€™m glad it appears it works, but however Iā€™m a little suspicious so I inputted this.


Enter the number of guests: 30
Enter the number of parties: 1
The probability that two guests have the same birthday is 100.00%

I donā€™t think thatā€™s possible. :rofl:

Maybe itā€™s because I donā€™t understand the Birthday Paradox problem that well. What do you guys think?

Well you only ran 1 birthday party, so you were either going to get 100% or 0% as your two possible results. Notice how the more parties you run, the closer it converges on 70%? And when you increase the number of guests, it shoots up to even higher?

Pretty sure thatā€™s approximately the right answer for the problem. Check Wikipedia: http://en.wikipedia.org/wiki/Birthday_problem

You simulated one party, and that one party did have a pair with the same birthday. So your simulation showed that 1 out of 1 party had a birthday pair, so it saw 100% of the parties had a pair. If you ran that simulation a few more times with the same parameters, eventually you would see a party with no match, and the probability according to the simulation would be 0 out of 1, or 0%.

Are you going to figure in leap years in your simulation? :slight_smile:

Ah, I see it now thanks again!

Nope, my professor was cool enough to not require us to include leap years.

Anyway Iā€™m going to see if I can clean it some more and thatā€™s that. Thanks again guys!

Oh and Pertho, if youā€™re interested in learning, I can upload all the notes my professor made for C programming for you to download.

Anyway off to marathon study for my Calc II midterm. :sad:

Just for shits and giggles, can we even figure in leap years to a problem like this?

I suppose what you could do is assign a number for the birthday over the course of 4 years. So that would be 365 + 365 + 365 + 365 days, + 1 more for leapyear. That gives us 1461 possible birthdays. Modify the birthday assigning code to be like this:




for(i = 0; i < numGuests; i++)
{
    int day = rand() % 1461;
    if(day == 1460) //this is our leapyear condition
      birthday* = 365;
    else
      birthday* = day % 365; //just truncate it down to one of the original 365 days
}



Though that ignores the fact that rand() probably gives us 1/2 as likely a chance to get the end numbers of the possibilities (if it does round down truncation) . But I think mathematically itā€™s probably correct?

Of course it doesnā€™t change the results very much haha



Enter the number of guests: 30
Enter the number of parties: 1000000
70.57%


Iā€™m running a 1 billion simulation test but itā€™s taking awhile of course ; )