Get clicked item of array - java

I've created a grid of objects called Cell. Each cell has following properties:
x coordinate
y coordinate
width
height
The width of a cell is equal to it's height. Every cell has got the same width/height.
There are 9*9 cells, one beside another, created by this algorithm:
cells = new Cell[9][0];
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
cells[i][j] = new Cell(i*cellWidth, j*cellHeight);
}
}
The cell's constructor asks for the x and y coordinates. Now we got a grid of Cells.
When I touch the screen, I know the x and y coordinates where I touched the screen. This cell I touched should run a method called isTouched.
How can I find out which cell I've touched?
I've tried this algorithm:
public boolean isTouched(int zx, int zy) {
if((zx >= x && zx <= x+cellSize) && (zy >= y && zy <= y+cellSize)) {
return true;
}else {
return false;
}
}
zx and zy are the touched coordinates. It checks whether the touched x axis is bigger or equal the cell's own x coordinate and if it's smaller than the cell's x coordinate + the cell's width. Same thing with the y coordinate.
It won't work as when I tap on a cell of the first row, the first element in the first row gets selected. When tapping on an element in the fifth row, the fifth element in the fifth row gets selected although I've pressed on another cell.
Here's a screenshot
I can't find my mistake, any suggestions? Thanks in advance

It would be more efficient and easier to compute the cell which contains the touch point.
Cell touchedCell(int x, int y) {
i = x / cellWidth;
j = y / cellHeight;
if (i >= 9 || j >= 9 || i < 0 || j < 0)
return null;
else
return cell[i][j];
}
The array size is also off:
cells = new Cell[9][0];
This is whats causing the strange effect as there are only 9 cells in the array, since j will be multiplied by 0 when indexing cell[i][j] == cell[i][0] no matter what j.
should be
cells = new Cell[9][9];

Related

Why doesn't my code flip image horizontally?

public void flipImageHorizontally(){
this.redisplayImage();
for(int x = 0; x < this.image.length; x++)
for(int y = 0; y < this.image[0].length; y++){
this.image[x][y] = this.image[x][this.image[0].length - 1 - y];
}
}
The code runs but it doesn't perform the action intended. It is supposed to flip the image horizontally, but instead it only flips half of the image.
Let's say you have an image two pixels wide and one pixel high:
1 2
After the first iteration of your loop, the end pixel will be swapped to the beginning (image[0][0] = image[0][2 - 1 - 0];):
2 2
But now you lost the original value of image[0][0]! So when you do the swap image[0][1] = image[0][2 - 1 - 1];, you are copying the second half of the image back to itself.
The right answer is to use a buffer so you don't overwrite the swap:
for(int y = 0; y < this.image[0].length / 2; y++) {
int buffer = this.image[x][y];
this.image[x][y] = this.image[x][this.image[0].length - 1 - y];
this.image[x][this.image[0].length - 1 - y] = buffer;
}
Integer truncation ensures that this.image[0].length / 2 is an efficient bound. For even numbers, you iterate exactly the first half. For odd numbers, you iterate the first half, not including the middle pixel. That's a good thing, because the middle does not need to be swapped.
You need to iterate up to the middle, and swap pixels that are on the left with pixels that are on the right. Otherwise you end up overwriting your changes.
public void flipImageHorizontally() {
this.redisplayImage();
for(int x = 0; x < this.image.length; x++) {
for(int y = 0; y < this.image[x].length / 2; y++) {
int pixel = this.image[x][y]; // assuming int
this.image[x][y] = this.image[x][this.image[x].length - 1 - y];
this.image[x][this.image[x].length - 1 - y] = pixel;
}
}
}
In this code
the pixel variable temporarily holds the value on the left;
the value on the left gets assigned the value on the right;
the value on the right gets the value that was originally on the left (i.e. whatever is in pixel).
Notes:
I maintained your naming of x and y, even though it's counter-intuitive because it makes it look like you're performing a vertical flip instead of a horizontal one.
I don't know the data type of the array; I assumed int, but it might be a float array, Pixel objects, or something else.
I don't know what this.redisplayImage(); is supposed to do, and whether it's in the right location.

Centroid of matrix

Given a 2D array, I am required to come up with an algorithm which outputs the center of mass. I came up with algorithm below, however, it is producing incorrect solution when the array size is increased to 10 x 10 matrix. I wrote and ran the algorithm using java. I have not provided the codes here, but just an explanation of my algorithm as i feel that it is not right. However, I am unable to find out why.
Store into an array: Mean of each row
Store into an array: Mean of each column
The algo below is used for row and column:
Loop through the row array,
if(row = 1){
value = (mean of row 1) - (mean of row 2 + mean of row 3+ mean of row 4)
}else if(row =Length of array){
value = (mean of row 1 + mean of row 2 + mean of row 3) - (mean of row 4)}
else{
value = (mean of rows until ith row) - (ith row till end of array)
}
final value = lowest value;
I know that it is supposed to deal with mean of the rows and columns. So in my algorithm, i find out the means of rows and columns and then conduct the calculation shown above. The same algo applies to the columns.
Any and all help is appreciated. Maybe, my understanding of center of mass is incorrect. If something is not clear, then do ask. This is my own algorithm, created from my understanding of center of mass, so if its not clear, please do ask. Thank you!
Expanding on my comment, you should be able calculate the center of mass as follows:
foreach col
foreach row
massvector.x += matrix[col][row] * col
massvector.y += matrix[col][row] * row
totalmass += matrix[col][row]
massvector.x /= totalmass
massvector.y /= totalmass
The idea is based on the section "A system of particles" in https://en.wikipedia.org/wiki/Center_of_mass: treat the matrix elements as equally spaced particles laid out on a 2D plane. The position of each element is equal to its position within the matrix, i.e. column and row, while the particle mass is the value of that cell/element/matrix position.
Example-Implementation using your (now deleted) test case:
double[][] matrix = new double[][]{
{0.70,0.75,0.70,0.75,0.80},
{0.55,0.30,0.20,0.10,0.70},
{0.80,0.10,0.00,0.00,0.80},
{0.70,0.00,0.00,0.00,0.80},
{0.80,0.90,0.80,0.75,0.90}};
double cx = 0;
double cy = 0;
double m = 0;
for(int x = 0; x < matrix.length; x++ ) {
for(int y = 0; y < matrix[x].length; y++) {
cx += matrix[x][y] * x;
cy += matrix[x][y] * y;
m += matrix[x][y];
}
}
//those are center's the cell coordinates within the matrix
int cmx = (int)(cx/m);
int cmy = (int)(cy/m);
//whatever you'd need that value for (the position is more likely what you're after)
double centerOfMassValue = matrix[cmx][cmy];
The example above would return coordinates 2/2 with is the center of the 5x5 matrix.
You need to do a weighted average so for an 3x3 array,
x̄= (mass(col1)*1 + mass(col2)*2 + mass(col3)*3) / (mass(col1) + mass(col2) + mass(col3))
and similarly for y replacing columns with rows.
Once you have those two values, the pair of them will tell you the x and y coordinates of the center of mass for your array.
See example one in the following link if you need a visual example: http://www.batesville.k12.in.us/physics/APPhyNet/Dynamics/Center%20of%20Mass/2D_1.html
I assume that since you are storing the weights in a matrix, that the position in the matrix will correspond with the coordinates of the weight where the column index is x row index is y. Thus a weight at row=2,col=3 we will take to be (3,2) on the x/y coordinate system.
This code follows the solution for center of mass from a system of particles on Wikipedia:
public static Point2D.Double getCenterOfMass( double[][] matrix) {
double massTotal = 0;
double xTotal = 0;
double yTotal = 0;
for (int rowIndex = 0; rowIndex < matrix.length; rowIndex++) {
for (int colIndex = 0; colIndex < matrix[0].length; colIndex++) {
massTotal += matrix[rowIndex][colIndex];
xTotal += matrix[rowIndex][colIndex] * colIndex;
yTotal += matrix[rowIndex][colIndex] * rowIndex;
}
}
xTotal /= massTotal;
yTotal /= massTotal;
return new Point2D.Double(xTotal,yTotal);
}
Full working code here.

Java Sudoku brute force solver, how does it work?

So you find the code below here. Most of the code I understand, but there is one bit I don't. The place where we create the boolean array called digits and the bit after that 3 * (x / 3).
I think it's used to check if each square in the sudoku has 9 unique numbers as well, but I'm not sure on how I can explain this to let's say someone next to me.
Why do I need the array of boolean here? Can someone explain to me what it is doing and why?
Kind regards!
public int[][] solvePuzzle(int[][] matrix) {
int x, y = 0;
boolean found = false;
// First we check if the matrix contains any zeros.
// If it does we break out of the for loop and continue to solving the puzzle.
for (x = 0; x < 9; x++) {
for (y = 0; y < 9; y++) {
if (matrix[x][y] == 0) {
found = true;
break;
}
}
if (found) {
break;
}
}
// If the puzzle doesn't contain any zeros we return the matrix
// We now know that this is the solved version of the puzzle
if (!found) {
return matrix;
}
boolean digits[] = new boolean[11];
for (int i = 0; i < 9; i++) {
digits[matrix[x][i]] = true;
digits[matrix[i][y]] = true;
}
int boxX = 3 * (x / 3), boxY = 3 * (y / 3);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
digits[matrix[boxX + i][boxY + j]] = true;
}
}
// We loop over all the numbers we have to check if the next number fits in the puzzle
// We update the matrix and check recursively by calling the same function again to check if the puzzle is correct
// If it's not correct we reset the matrix field to 0 and continue with the next number in the for loop
for (int i = 1; i <= 9; i++) {
if (!digits[i]) {
matrix[x][y] = i;
if (solvePuzzle(matrix) != null) {
return matrix;
}
matrix[x][y] = 0;
}
}
// The puzzle can't be solved so we return null
return null;
}
I have added some explanation as comments inline:
//we need to know what digits are we still allowed to use
//(not used in this row, not used in this column, not used in
//the same 3x3 "sub-box")
boolean digits[] = new boolean[11];
//so we run through the rows/coumns around the place (x,y)
//we want to fill in this iteration
for (int i = 0; i < 9; i++) {
//take a used number from the row of x (matrix[x][i]) and mark it
// as used
digits[matrix[x][i]] = true;
//take a used number from the column of y (matrix[i][y]) and mark it
// as used
digits[matrix[i][y]] = true;
}
//find the top-left corner of the sub-box for the position (x,y) we
//want to fill in
//example: x is 8 -> 3 * 8/3 -> 6, so we start from 6
int boxX = 3 * (x / 3), boxY = 3 * (y / 3);
//iterate through the sub-box horizontally and vertically
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
//take a used number from the sub-box and mark it
// as used
digits[matrix[boxX + i][boxY + j]] = true;
}
}
There seem to be two issues you are unclear on:
The boolean array - this array is used to track which digits have been used already on a specific row or column. So imagine a row of tick boxes each with a digit written next to it (the array index) - these boxes are checked or unchecked to show a digit has been used or not.
The expressions 3* (x/3) and 3 * (y/3) - what you need to remember here is that this is integer division (that means the result of the division is always rounded down to an integer. For example if x=1 then 3 (x/3) is 3 (1/3) is 3 * (0) =0 (whereas if this was float division the result would be 3*(0.3333)=1. So these maths expressions essentially change you number to the next lowest multiple of three - that is 1 -> 0, 2 -> 0, 3 -> 3, 4 -> 3 etc.

Searching a grid recursively by triangular numbers

I have a 36x25 grid of nodes that I wish to search through all triangular numbers from the corner opposite of the hypotenuse. Here's psuedocode for what I was considering, but this method only works until it hits the next corner of the grid, and I'm sure there is a much simpler way to do this recursively, I just am having difficulty figuring it out.
for(int iteration; iteration < maxDistance(49); iteration++)
{
int xAdd = iteration;
int yAdd = 0;
while(xAdd != 0)
{
checkStuff(nodeGrid[x+xAdd][y+yAdd]);
xAdd--;
yAdd++;
}
}
What I want program to do:
[0][1][2][3][4][5]
[1][2][3][4][5][6]
[2][3][4][5][6][7]
[3][4][5][6][7][8]
[4][5][6][7][8][9]
check in this order. So first check all tiles with value 0, then 1 and so on.
Note: in this case my function will only work up until the 4th set up tiles. Any further and it will reach out of bounds.
/**
* Only works for rectangular arrays
*/
public void iterateOver(Node[][] a){
int x_dim = a[0].length;
int y_dim = a.length;
for (int i = 0; i < x_dim + y_dim - 1; i++){
int x, y;
if (i < x_dim){
x = i;
y = 0;
}
else{
x = x_dim - 1;
y = i - x_dim + 1;
}
for (;x >=0 && y < y_dim; y++, x--){
doStuff(a[y][x]);
}
}
}
How it works
Picture your rectangular array:
[0][1][2][3][4][5]
[1][2][3][4][5][6]
[2][3][4][5][6][7]
[3][4][5][6][7][8]
[4][5][6][7][8][9]
There are clearly 6 columns and 5 rows (or 6 x values and 5 y values). That means that we need to do 6 + 5 - 1 iterations, or 10. Thus, the for (int i = 0; i < x_dim + y_dim - 1; i++). (i is the current iteration, measured from 0).
We start by columns. When i is less than the x dimension, x = i and y = 0 to start with. x is decremented and y is incremented until x is less than zero or y is equal to the y dimension. Then, we do a similar thing down the right hand side.

Algorithm: Put y balls into x boxes where x <= y

I have a problem that comes up when I was developing an app on Android. However, the problem is:
There are x boxes and y balls where x <= y, and I want to distribute the balls to put them inside the boxes in order. For example: 3 boxes; box A, box B and box C - and 5 balls; ball 1, ball 2, ball 3, ball 4, ball 5.
What I need is to put the first ball ball 1 inside box A, and ball 5 inside box C and the other balls are distributed between them all (does not matter if one box has more balls than the others). Here is a loop (missing an increment value) that simulates the problem:
int boxCount = 0; // first box is 0 and last box is x
int numOfBalls = y;
for(int i = 0; i < numOfBalls; i++, boxCount += ???)
{
boxes.get(boxCount).add(balls.get(i));
}
What equation should I used instead of ??? to solve the problem?
EDIT:
Since x <= y, that means:
None of the boxes should be empty.
The difference between the boxes' balls number should not be more than 1.
EDIT2
By in order, I meant this:
A B C
---------
1 3 5
2 4
not
A B C
---------
1 2 3
4 5
int flag;
int lastBallAdded = 0;
int k = numOfBalls/numOfBoxes;
int m = numOfBalls%numOfBoxes;
for(int i = 0; i < numOfBoxes; i++, lastBallAdded+=k+flag) {
flag = i<m;
for(int j=lastBallAdded;j<lastBallAdded + k + flag;j++)
boxes.get(i).add(balls.get(j));
}
This is the reasoning behind this solution:
by the definition of the problem, the algorithm should put k= numOfBalls/numOfBoxes balls in each box, except for the firsts m = numOfBalls%numOfBoxes boxes, where you should put k+1 balls.
You can alternatively write it as
int i;
for(i = 0; i < m; i++) {
//add k+1 balls
}
for(;i<numOfBoxes; i++) {
//add k balls
}
You can distribute (int)n/k balls in each of the first k-1 boxes and the rest in the last box. This will be simplest to code.
With this: boxCount += (i % (numOfBalls/numOfBoxes) == 0 && boxCount < numOfBoxes-1 ? 1 : 0)
int ball = 0;
for( int box = 0; box < x; ++box )
while ( x * (ball+1) <= y * (box+1) )
boxes.get(box).add(balls.get(ball++));
Loop invariant: The left k boxes contain fraction k/x of the balls (rounded).
Ok, new try:
boxCount = ((i * nbrOfBoxes) / nbrOfBalls) + 1;
Note, the index of the balls are numbered from 0 to 4 (as in the for-loop). Remove the + 1 if yo would like the boxCount to be zero based.

Categories

Resources