How to populate 2D boolean array between two coordinates? - java

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.
}
}

Related

A question about for-loop condition in java

I am working on the problem below:
Given a non-empty array of digits representing a non-negative integer, plus one to the integer.
Eg:[1,2,3] Output:[1,2,4]
My approach is usring carry to calculate the singular digit from end to start.
I got 2 version of this problem. First one does not work when the input is [1,4,4,9].However, the second one is wokring. In the second version, I change the for-loop condition. I wonder why this happened? Could anyone help me with this? Any help would be appreciated! Thanks!
Version 1:
public static int[] plusOne(int[] digits) {
int sum = 0;
int len = digits.length;
int carry = (digits[digits.length -1]+1)/10;
digits[digits.length -1] = (digits[digits.length -1]+1)%10;
for (int j = len-2;j >= 0;j--){
carry = (digits[j]+carry)/10 ;
digits[j] =(digits[j]+carry)%10 ;
}
if (carry==0) return digits;
else{
int[] res = new int[len+1];
res[0] = 1;
int i = 0;
for (int j=1;j<res.length;j++){
res[j] = digits [i++];
}
return res;
}
}
Version 2:
public static int[] plusOne(int[] digits) {
int sum = 0;
int len = digits.length;
int carry = (digits[digits.length -1]+1)/10;
digits[digits.length -1] = (digits[digits.length -1]+1)%10;
for (int j = len-2;j >= 0;j--){
int temp = digits[j]+carry;
carry = (temp)/10 ;
digits[j] =(temp)%10 ;
}
if (carry==0) return digits;
else{
int[] res = new int[len+1];
res[0] = 1;
int i = 0;
for (int j=1;j<res.length;j++){
res[j] = digits [i++];
}
return res;
}
Posting a longer answer after all...
The only difference in those two code snippets are the first for loops. Your first example doesn't work as you expected.
for (int j = len-2;j >= 0;j--){
carry = (digits[j]+carry)/10 ;
digits[j] =(digits[j]+carry)%10 ;
}
Here the problem lies in the line carry = (digits[j]+carry)/10 ;
You're changing the variable carry, but this value is being used in the next line.
Let's say, carry was 1 and digits[j] is 5. After carry = (digits[j]+carry)/10; the variable carry changed to 0 and the subsequent calculation of digits[j] results in 5 instead of 6.
The second example works, because you're introducing an intermediate variable temp:
for (int j = len-2;j >= 0;j--){
int temp = digits[j]+carry;
carry = (temp)/10 ;
digits[j] =(temp)%10 ;
}
temp is calculated once and then only read from, so carry and digits are not dependant on each other any more. In turn, you will get the result you expect.

Printing 2d array in app gives blank screen

i made 2d array that contains names and task.
the function give random task to the users.
when i try to print the array that contain the users and the random tasks i get a blank screen.
public String[][] start() {
int[] taken = new int[this.numberOfRowsT()];
String[][] h = new String[numberOfRowsN()][(numberOfRowsT()) / (numberOfRowsN()) + 1];
int a = 1;
int x;
for(int b = 0; b < this.numberOfRowsN(); b++){
h[b][0] = this.getUsersByID(b+1).toString();
}
while (a != this.numberOfRowsT()) {
x = (int) Math.random() * ((this.numberOfRowsT()) + 1);
for (int j = 0; j < taken.length; j++) {
if (x == taken[j]) {
j = -1;
x = (int) Math.random() * ((this.numberOfRowsT()) + 1);
}
}
taken[a] = x; // acceptable num from here
h[((a % this.numberOfRowsN()) + 1)][this.numberOfRowsN() % a] = this.getTaskByID(x).toString();
a++;
}
return h;
}
public void onClick(View v) {
String[][] h = mydb.start();
for (int i = 0; i < mydb.numberOfRowsN(); i++) {
for (int j = 0; j < mydb.numberOfRowsT() /
mydb.numberOfRowsN(); j++)
if (h[i][j] != null)
l.append(h[i][j]);
l.append("\n"); // Append newline after every row
}
}
});
}
Here:
String[][] h = mydb.start();
I guess you want to use that 2D array to collect all the strings to print.
Thing is: you only declare and fill that array.
But it is a local variable, and it goes out of scope as soon as onClick() has run.
Thus: if you want to print things, then you need to do something with the data you collected. Either put into some UI element, or at least log it, or send to System.out.printn() (that of course only works when you have a console, and isn't a viable thing for an Android app).

Stop a loop after a certain amount of iterations, instead of when a max value is met

JAVA:
I want a for loop that doesnt stop when i is a certain number, but rather after x iterations. Is there any way to do that?
public static int seven_sum(int num) {
int sum = 0;
for (int i = 7; i <= WHAT GOES HERE; i = i * 10 + i) {
sum = sum + i;
}
return sum;
}
You can declare multiple variables of the same type in a for-loop:
public static int seven_sum(int num) {
int sum = 0;
for (int i = 7, iterations = 0; iterations < (number of iterations); i = i * 10 + i, iterations++) {
sum = sum + i;
}
return sum;
}
Let's assume you have a certain value summing up in your loop and you want to stop the loop if the value exceeds a certain border. You can just add an if statement that checks the value:
public static void main(String args[]) {
// some value to hold a sum
int valueSum = 0;
for (int i = 0; i < 1000; i++) {
// in every iteration step, add the current value of i to valueSum
valueSum += i;
// print the current values of i and valueSum
System.out.println("Iteration no " + i + ", value sum = " + valueSum);
// stop looping if valueSum becomes 500 or greater
if (valueSum >= 500) {
break;
}
}
}
Please check the console output to get a better understanding of for loops and iteration in general.
The only case i can think of is: if x (number of iterations) is greater than i (your index which may depend on some input values like array length etc.) If that is the case you can combine an infinite loop with a break statement:
int iterations = 0;
for(int i = 0; true ; i++){
System.out.println("iterations count = " + ++iterations);
if(iterations == 10) break;
}
or even without declaring an index:
int iterations = 0;
for( ; ; ){
System.out.println("iterations count = " + ++iterations);
if(iterations == 10) break;
}
or if you need two or more independent variables
int x = 10; //number of iterations wanted
for(int i = 7, j = 0; j<= x; i = i * 10 + i , j++){
// do something
}

Birthday probability: wrong output

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.

Java program hangs at same random spot consistently

I had to do a program that would generate 30 graphs in total, with 5 having 10 unique edges, 5 having 20 unique edges, etc up to 60. I then had to take the average amount of components across in each of the 5 graphs. However, my program is hanging consistently in the same spot. It is when it is trying to do the 16th graph and the 11th edge that it fails, all the time. I left out the connected components static method since that is irrelevant to the problem, I believe. Note this is a rough draft of an earlier optimized copy, both get hung at the same place.
First, I make one graph with the 26 vertices required and then put that same graph into each of the 30 spots in the array and then I put the unique edges into each graph.
The edgeIs method and the indexIs method are in the graph ADT I am using.
Here is the code:
import ch05.queues.LinkedUnbndQueue;
import ch05.queues.UnboundedQueueInterface;
import java.util.Random;
public class UniqueEdgeGraph2 {
public static void main (String[] args) {
final int numGraphs2 = 5;
int numEdges = 10;
double sum = 0;
int index = 0;
Random rand = new Random();
int randomNum1 = 0, randomNum2 = 0, flag = 0;
UnweightedGraph<Integer>[] graphArray = (UnweightedGraph<Integer>[]) new UnweightedGraph[30];
UnweightedGraph<Integer> graph;
for (int i = 0; i < 30; i++)
graphArray[i] = new UnweightedGraph<Integer>();
for (int i = 0; i < 30; i++)
for (int j = 0; j < 26; j++)
graphArray[i].addVertex(j);
for (int i = 0; i < 6; i++) { // it is done 6 times because 30 graphs are needed in total and numGraphs is 5
for (int j = 0; j < numGraphs2; j++) {
for (int k = 0; k < numEdges; k++) {
while (flag == 0) {
randomNum1 = rand.nextInt(26);
randomNum2 = rand.nextInt(26);
if (graphArray[index].edgeIs(randomNum1, randomNum2) == false) {
graphArray[index].addEdge(randomNum1, randomNum2);
flag = 1;
}
}
flag = 0;
}
sum += CountConnectedComponents(graphArray[index]);
index++;
}
System.out.println("Average # of Connected Components for five graphs with " + numEdges + " unique edges is: "
+ sum/5.0);
sum = 0;
numEdges += 10;
}
}
public boolean edgeIs(T fromVertex, T toVertex)
// If edge from fromVertex to toVertex exists, returns true
// otherwise, returns false.
{
int row;
int column;
row = indexIs(fromVertex);
column = indexIs(toVertex);
return (edges[row][column]);
}
private int indexIs(T vertex)
// Returns the index of vertex in vertices.
{
int index = 0;
while (!vertex.equals(vertices[index]))
index++;
return index;
}
I figured out what the error was. I was pointing to the same graph for all 30 array indices. So instead of making 30 different graphs, I pointed the entire array to one graph. This made it impossible to eventually find a unique edge to put in, which caused an infinite loop instead of it just hanging like I thought it was.
I edited the code to reflect the changes I made to make it work. It is still in rough shape but it just needs to be cleaned up.
Thanks to everybody who commented.

Categories

Resources