Birthday probability: wrong output - java

The code below is supposed to generate random day of year, and matche every 2 people who have same birthday. This is know as birthday problem. The code works but the output is wrong.
public double simulate(int size, int count) {
Random random = new Random();
double x[] = new double[size];
double matches = 0;
boolean isMatch = false;
random.setSeed(count);
for (int i = 0; i < count; i++) {
for (int j = 0; j < size; j++) {
x[j] = random.nextInt(365);
for (int k = j + 1; k < size; k++) {
if (x[j] == x[k]) {
matches++;
isMatch = true;
break;
}
}
if (isMatch) {
isMatch = false;
break;
}
}
}
return (matches/count)*100;
}
and here is the Expected output result
simulate(number of people,number of simulation)
simulate(5, 10000) output = 2.71
simulate(7, 5000) output = 5.34
simulate(2, 10000) output = 0.27
simulate(9, 10000) output = 9.47
simulate(30, 20000) output = 70.675
simulate(15, 50000) output = 25.576
simulate(35, 50000) output = 81.434
simulate(45, 50000) output = 94.2
and this what Actual output :
simulate(5, 10000) output = 2.54
simulate(7, 5000) output = 5.64
simulate(2, 10000) output = 0.18
simulate(9, 10000) output = 9.05
simulate(30, 20000) output = 68.98
simulate(15, 50000) output = 25.12
simulate(35, 50000) output = 79.90
simulate(45, 50000) output = 92.99
thanks for you time .

There is one big problem in your code. You're initializing the array x with random data, but before you've fully initialized it, you are already checking if there are two values that are the same. At that point, the end of the array will not yet be fully initialized. Change that to:
// First fully filly the array x with values
for (int j = 0; j < size; j++) {
x[j] = random.nextInt(365);
}
// And then go checking for duplicates
for (int j = 0; j < size; j++) {
// etc.
After that, your results will be a closer to the expected output, but still not exactly the same. That could have something to do with the exact value for the random seed.

Related

How to populate 2D boolean array between two coordinates?

I'm trying to create a daily time block for my calendar app. I have an idea of creating a 2D array representing all the minute in a day:
final int hour = 24, min = 60;
boolean dayBlock[][] = new boolean [hour][min];
//Initialize the array. true = available, false =
busy.
for (int j = 0; j < 24; j++) {
for (int i = 0; i < 60; i++) {
dayBlock[j][i] = true;
}
}
However, I'm struggling how to write an algorithm to populate from (startHour, startMin) to (endHour, endMin) for an event with precision.
Since I'm doing this for multiple events, I can't just go over and then backtrack since it will mess up the previous event time-block.
To mark something ranging from (startHour, startMin) to (endHour, endMin)
// mark false for the remaining minutes in first hour
for (int i = startMin; i < 60; i++) {
dayBlock[startHour][i] = false;
}
// mark false for every minute after first hour and before last hour
for (int j = startHour+1; j < endHour; j++) {
for (int i = 0; i < 60; i++) {
dayBlock[j][i] = false;
}
}
// mark false for the remaining minutes in last hour
for (int i = 0; i < endMin; i++) {
dayBlock[endHour][i] = false;
}
I think you should probably rethink your idea of using a 2D array.
You are trying to represent time, which is naturally not two dimensional, but one dimensional.
Instead of a 2D array, why not use simple 1D array like this:
boolean dayBlock[] = new boolean[hour * minute];
To calculate where a given time is represented in the array, just use:
int start = theHour * 60 + theMinute;
Another option could be to think of an imaginary index for your 2d array from 0 to 1440 (24*60), which enables you to make something like below for your params (startHour, startMin) (endHour, endMin):
int startHour = 6;
int startMin = 15;
int endHour = 8;
int endMin = 0;
int strat = startHour * 60 + startMin;
int end = endHour * 60 + endMin;
for(int i = strat; i <= end; i++){
dayBlock[i/60][i%60] = false;
}
// Take input from user for start and end hour and start and end minuted and validate the boundary values.
int startHour,endHour,startMinute,endMinute;
for (int j = startHour; j <= endHour; j++) {
int i = 0;
if(j==startHour){
i= startMinute;
}
for (; i < 60; i++) {
if(j==endHour && i> endMinute) {
break;
}
dayBlock[j][i] = ;// if busy set false or true if available.
}
}

Printing array that was filled in a for loop

I am coming today with a very basic task that somehow confused me really hard.
I have an array that looks like that :
Here is the code:
double population[][] = {{281.0, 296.0, 325.0, 371.0, 384.5},
{298.6, 241.2, 301.2, 342.8, 388.7},
{362.9, 284.1, 276.8, 353.6, 395.1},
{393.4, 344.8, 295.6, 298.3, 375.0}};
int year[] = {2011, 2016, 2021, 2026, 2031};
String ageGroup[] = {"15-19", "20-24", "25-29", "30-34",};
String output = "Actual and Projected Population in thousands by Age Group (CSO 2016)";
output += String.format("\n%10s", "");
for (int i = 0; i < year.length; i++) {
output += String.format("%10s", year[i]);
}
output += String.format("%10s", "%Change");
double change[] = new double[ageGroup.length];
for (int i = 0; i < population.length; i++) {
output += String.format("\n%10s ", ageGroup[i]);
for (int j = 0; j < population[i].length; j++) {
output += String.format("%10.1f", population[i][j]);
}
change[i] = (((population[i][4] - population[i][0])/
population[i][0]) * 100);
output += String.format("%10.1f", change[i]);
}
output += String.format("\n\nTotal (15 - 34): ");
System.out.println(output);
}
As you can clearly see I am missing the bottom values - 1335.9, 1166.1, 1198.6, 1543.3. These values are gained by adding full year e.g. 2011 - 281 + 298.6 + 362.9 + 393.4
I cannot figure out how to make a for loop in order for this to print out the way I want to.
I tried :
double total[] = new double[ageGroup.length];
double hold = 0;
for(int i = 0; i < population.length; i++){
total[i] += hold;
for(int j = 0; j < population[i].length; j++){
hold += population[j][i];
I also tried adding it here
for (int i = 0; i < population.length; i++) {
output += String.format("\n%10s ", ageGroup[i]);
for (int j = 0; j < population[i].length; j++) {
output += String.format("%10.1f", population[i][j]);
}
change[i] = (((population[i][4] - population[i][0])/
population[i][0]) * 100);
output += String.format("%10.1f", change[i]);
total[i] = (population[0][i] + population[1][i]+ population[2][i]+population[3][i]+population[4][i]);
}
Now I am just left confused on how such an easy task made me stuck so hard.
It is a crime that instructors do not teach OO thinking out of the gate, forcing students to muddle through arrays rather than modeling the domain. sigh.
There are two keys here, I think. First, separate the calculation from presentation. Second, realize that rows are age groups and columns are years. Really there should be methods for this stuff rather than just in a single main method. Also, the title and some fluff can be fixed in the final output.
Also, rather than hard coding, e.g., [4], this code uses the .length of the array to make it somewhat easier to deal with adding another year or another age group.
//
// a 2d array, where row is for a given agent group, and column
// is for a given year
//
static double population[][] = { { 281.0, 296.0, 325.0, 371.0, 384.5 },
{ 298.6, 241.2, 301.2, 342.8, 388.7 },
{ 362.9, 284.1, 276.8, 353.6, 395.1 },
{ 393.4, 344.8, 295.6, 298.3, 375.0 } };
static int year[] = { 2011, 2016, 2021, 2026, 2031 };
static String ageGroup[] = { "15-19", "20-24", "25-29", "30-34", };
public static void main(String[] args)
{
//
// hold the totals
//
double[] yearTot = new double[year.length]; // total by year
double[] agTot = new double[ageGroup.length]; //total by ag
double[] chngAG = new double[ageGroup.length]; //change
// loop over every age group
for (int ag = 0; ag < ageGroup.length; ++ag) {
// get the population for the age group, which is
// one row in the data
double[] valsForAG = population[ag];
// loop over every year, which a column in a given age group
for (int yr = 0; yr < year.length; ++yr) {
// get the specific value
double valForAgInYear = valsForAG[yr];
// add to the total for the year and to the age group value
yearTot[yr] += valForAgInYear;
agTot[ag] += valForAgInYear;
} // for every year
int en = ageGroup.length;
int st = 0;
// after processing an age group, calculate the change
chngAG[ag] = ( ( (valsForAG[en] - valsForAG[st]) /
valsForAG[st]) * 100);
} // for every age group
//
// do the output
//
// header row
System.out.printf("%10s", "");
for (int y = 0; y < year.length; ++y) {
System.out.printf("\t%7d", year[y]);
}
System.out.printf("\t%10s%n", "%Change");
// data
for (int ag = 0; ag < ageGroup.length; ++ag) {
System.out.printf("%10s", ageGroup[ag]);
for (int yr = 0; yr < year.length; ++yr) {
System.out.printf("\t%7.1f", population[ag][yr]);
}
System.out.printf("%10.1f", chngAG[ag]);
System.out.println();
}
//output the totals
System.out.println();
System.out.printf("%10s", "Totals:");
for (int t = 0; t < yearTot.length; ++t) {
System.out.printf("\t%7.1f", yearTot[t]);
}
System.out.println();
}
Output
2011 2016 2021 2026 2031 %Change
15-19 281.0 296.0 325.0 371.0 384.5 36.8
20-24 298.6 241.2 301.2 342.8 388.7 30.2
25-29 362.9 284.1 276.8 353.6 395.1 8.9
30-34 393.4 344.8 295.6 298.3 375.0 -4.7
Totals: 1335.9 1166.1 1198.6 1365.7 1543.3
public static void main(String[] args) {
double population[][] = {{281.0, 296.0, 325.0, 371.0, 384.5}, {298.6, 241.2, 301.2, 342.8, 388.7}, {362.9, 284.1, 276.8, 353.6, 395.1}, {393.4, 344.8, 295.6, 298.3, 375.0}};
//1. Step: Find the longest of the arrays
//You need this if the length of the arrays is different, for example:
/*
double population[][] = {
{281.0, 296.0, 325.0, 371.0, 384.5},
{298.6, 241.2, 301.2, 342.8, 388.7, 0},
{362.9, 284.1, 276.8, 353.6, 395.1, 1, 2},
{393.4, 344.8, 295.6, 298.3, 375.0, 0.5}
};
*/
int lengthOfLongestArray = population[0].length;
for(int i = 0; i < population.length; i++){
if(population[i].length > lengthOfLongestArray){
lengthOfLongestArray = population[i].length;
}
}
//2. Step: calculate the sum
double result[] = new double[lengthOfLongestArray];
for(int i = 0; i < population.length; i++){
for(int j = 0; j < population[i].length; j++){
result[j] += population[i][j];
}
}
System.out.println(Arrays.toString(result));
}
Explanation:
To avoid confusing loops and fancy logic I created an array which will hold the result of the calculation called result.
Step:
By setting the length of this result array to the length longest of the rows in the population 2D array (aka. matrix) we handle the situation when the rows are not exactly the same length (see the example I commented out).
Step:
Then we just loop through the 2D array and sum the values. As we go through of a row in your 2D array we can take the value from the 'j' position of the row we are checking and add it to the value we have in the 'j' position in the result array.
Cheers,
A.
double population[][] = { { 281.0, 296.0, 325.0, 371.0, 384.5 }, { 298.6, 241.2, 301.2, 342.8, 388.7 },
{ 362.9, 284.1, 276.8, 353.6, 395.1 }, { 393.4, 344.8, 295.6, 298.3, 375.0 } };
int year[] = { 2011, 2016, 2021, 2026, 2031 };
String ageGroup[] = { "15-19", "20-24", "25-29", "30-34", };
String output = "Actual and Projected Population in thousands by Age Group (CSO 2016)";
output += String.format("\n%10s", "");
for (int i = 0; i < year.length; i++) {
output += String.format("%10s", year[i]);
}
output += String.format("%10s", "%Change");
double change[] = new double[ageGroup.length];
for (int i = 0; i < population.length; i++) {
output += String.format("\n%10s ", ageGroup[i]);
for (int j = 0; j < population[i].length; j++) {
output += String.format("%10.1f", population[i][j]);
}
change[i] = (((population[i][4] - population[i][0]) / population[i][0]) * 100);
output += String.format("%10.1f", change[i]);
}
output += String.format("\n\nTotal (15 - 34): ");
// here i changed the code
// this loop will print the last from (15 to 35)
// the outer loop iterate like 2011 2016 and so one
for (int i = 0; i < 5; i++) {
double temp = 0;
// the inner loop iterate from up to down and add values
for (int j = 0; j < 4; j++) {
temp = temp + population[j][i];
}
output += String.format("%10.1f", temp);
}
System.out.println(output);

fibonacci in Java

I am trying to create a program which finds the sum of even numbers below 4 million the Fibonacci sequence. I know there is a much simpler way of doing this, but I wanted to see if it would work with arrays. I have never really used arrays before as I am fairly new to Java, which is why I wanted to see if this worked with arrays. The main problem that I have is with the for statement. How would I see if the contents of fibarray[i] is less than 4000000?
Also, is it OK if I do the thing with the fibarray = new int[i]?
public static void main(String[] args) {
int[] fibarray;
int numcount = 0;
int i = 0;
long sum = 0;
fibarray = new int[i];
fibarray[0] = 0;
fibarray[1] = 1;
for(i = 0 , fibarray[i] < 4000000, i++;;){
fibarray[i] = fibarray[i - 1] + fibarray[i - 2];
}
}
I apologise if this sounds really stupid.
Any help would be much appreciated.
Thanks.
Well, you need to start your for loop with i = 2. And the for loop should be in this syntax
for(i = 2; fibarray[i] < 4000000; i++) {
fibarray[i] = fibarray[i - 1] + fibarray[i - 2];
}
See comments within the code:
public static void main(String[] args){
/*************************
* comments on your code
int[] fibarray; //use right java naming convention
int numCount = 0; //this variable is never used
int i = 0;
long sum = 0;
fibarray = new int[i];//you initialize an array of size 0.
fibarray[0] = 0; //you can't set value to array of size 0
fibarray[1] = 1; //you can't set value to array of size 0
//wrong syntax
for(i = 0 , fibarray[i] < 4000000, i++;;){
//use for(i = 0 ; fibarray[i] < 4000000; i++){
fibarray[i] = fibarray[i - 1] + fibarray[i - 2];
}
*******************************/
//Alternative code
//you don't need to keep all Fibonachi numbers found.
//you only use 3 numbers for every calculation
int size = 3;
int totalLimit = 4000000;
int[] fibArray = new int[size];
fibArray[0] = 0; fibArray[1] = 1;
int total = 0;
while( true ) {
fibArray[2] = fibArray[0] + fibArray[1] ;
if((fibArray[2]%2) ==0) { //even number
if((total + fibArray[2]) >= totalLimit) {
break;
}
total += fibArray[2];
}
fibArray[0] = fibArray[1] ;
fibArray[1] = fibArray[2] ;
}
System.out.println("Total "+ total );
}
Don't hesitate to ask for clarifications as needed.

Finding the mode of a 2D array

I'm trying to return the mode of a 2D array using a frequency array. I have an array, score, which is of length 10, and has 3 columns. Each column contains an int that is between 0 and 100.
I'm trying to find a way that will iterate through the array and return the modal value. What I have so far is:
int value = 0;
int[] freq = new int[100];
for (int row = 0; row < score.length; row++) {
for (int col = 0; col < score[row].length; col++) {
score[row][col] = value;
freq[value]++;
}
}
int largest = 0;
int mode = -1;
for (int i = 0; i < 100; i++) {
if (freq[i] > largest)
{
largest = freq[i];
mode = i;
}
}
System.out.println("modal score is: " +mode);
Problem is that this is just returning the modal score as 0, which it isn't.
You have a problem on generating the freq array. If I understand correctly, on the first double-for block you are trying to put the frequencies of the numbers inside the freq array.
But all you do is:
int value = 0;
.....
score[row][col] = value;
freq[value]++;`
firstly you are changing the score array,( which is a problem for you I guess...) and the you go to freq[0] and do ++. Obviously modal is 0, that number appears in all of the array.
SOLUTION: in the first double for block you should do:
value = score[row][col];
freq[value]++;
so I think you mixed up the order of the line, it should be the other way around.
private static void printMode(double[][] doubles) {
HashMap<Double , Double> map = new HashMap();
for (int i = 0; i < doubles.length; i++) {
for (int j = 0; j < doubles[i].length; j++) {
double temp = doubles[i][j];
if(map.get(temp)==null){
map.put(doubles[i][j],1.0);
}else {
double temp2 = (double) map.get(temp);
map.put(doubles[i][j],++temp2);
}
}
}
Object[] objects = map.values().stream().sorted().toArray();
Stream stream = map.entrySet().stream().filter(val-> val.getValue().equals(objects[objects.length-1]));
stream.forEach(System.out::println);
}
I think using Stream for finding mode is the best way.
use int instead of double doesn't cause any problems.
int value = 0;
int [] freq = new int [arr.length];
for (int i = 0; i < arr.length; i++){
for (int j = 0; j < arr[i].length; j++){
value = arr[i][j];
freq[value]++;
}
}
int largest = 0;
int mode = 0;
for (int i = 0; i < freq.length; i++) {
if (freq[i] > largest)
{
largest = freq[i];
mode = i;
}
}
System.out.println("modal score is: " +mode);

Generating non-duplicate numbers using Arrays, not ArrayList<> in Java

I'm doing the old Lotto exercise and I need to specifically use an Array[] of integers and not an ArrayList. I have what I thought would work, but I seem to be wrong. I looked for posts similar to these and all of them involved an ArrayList<>. Here is a partition of my code.
Integer[] lottoNums;
lottoNums = new Integer[7];
for(int i = 0; i < lottoNums.length; i++){
lottoNums[i] = randomNums.nextInt((59)+1);
if(i <= 5) {
if(lottoNums[i].equals(lottoNums[i+1])){
if(lottoNums[i] < 58 && lottoNums[i] > 1)
lottoNums[i] = lottoNums[i] +1;
}
}
else if(i >= 1) {
if(lottoNums[i].equals(lottoNums[i-1])){
if(lottoNums[i] < 58 && lottoNums[i] > 1)
lottoNums[i] = lottoNums[i] +1;
}
}
}
Arrays.sort(lottoNums);
System.out.print("Winning numbers: "+lottoNums[0]);
for (int i = 1; i < 6; i++) {
System.out.print(", " + lottoNums[i]);
}
System.out.print(System.getProperty("line.separator"));
System.out.println("Bonus Number: "+lottoNums[6]);
I need to get it to generate a number in between 1 and 59 and not duplicate. I was trying to pair it up with the value stored in the element before and after it (if it had one) and if it was equal to it, it would add 1 to it. I run it a few times and every once in a while im still getting duplicate numbers. How can i do this efficiently, using Arrays[] of integers ONLY?
EDIT:
Initialized array to remove NullPointerException.
Updated Code:
for(int i = 0; i < lottoNums.length; i++){
lottoNums[i] = randomNums.nextInt((59)+1);
}
for (int i = 0; i < 6; i++) {
int rnd = randomNums.nextInt((lottoNums).length-i);
int k = lottoNums[lottoNums.length-i-1];
lottoNums[lottoNums.length-i-1] = lottoNums[rnd];
lottoNums[rnd] = k;
}
Arrays.sort(lottoNums);
System.out.print("Winning numbers: "+lottoNums[0]);
//PRINTING LOTTO NUMBERS
for (int i = 1; i < 6; i++) {
System.out.print(", " + lottoNums[i]);
}
System.out.print(System.getProperty("line.separator"));
System.out.println("Bonus Number: "+lottoNums[6]);
You can do this by switching the selected number with the last number in the array each time, and then selecting the next from the prefix you have not yet stored:
for (int i = 0; i < 6; i++) {
int rnd = randomNums.nextInt(numbers.length-i);
int k = numbers[numbers.length-i-1];
numbers[numbers.length-i-1] = numbers[rnd];
numbers[rnd] = k;
}
At the end of this loop your selected numbers will be in numbers[numbers.length-7..numbers.length-1], etc.
I would use two arrays. Each time you draw a number see if it exists in the second array. If not use it and add it to the second array.

Categories

Resources