Shifting elements in an array a particular way - java

The goal of this method is that I have a 2D array filled with Bubble objects and I am trying to shift everything in the array that does not have a color value of 0 down and leave the color 0 at the top of the column.
At the moment it turns every spot into a bubble with a value of 0. I'm thinking its a small logic error that im missing but I have been trying for 3 days now and cant see my issue. *Clarification: myBoard is initialized as new Bubble [15][15]; and the Bubble Constructor is (int color, int row, int col)
public void shiftBoardDown() {
int currentC = 0;
while(currentC < 15){
Bubble [] temp = new Bubble [15];
int hits = 14;
for(int i = 14; i <= 0; i--){
if(this.myBoard[i][currentC].getColor() != 0){
temp[hits] = new Bubble(this.myBoard[i][currentC].getColor(), hits, currentC);
hits--;
}
}
while(hits >= 0){
temp[hits] = new Bubble(0, hits, currentC);
hits--;
}
for(int r = 0; r < 15; r++){
this.myBoard[r][currentC] = temp[r];
}
currentC++;
}
}

I'm guessing
if(this.myBoard[i][currentC].getColor() != 0)
Never gets triggered and the following loop is entered with hits==14.
while(hits >= 0){
temp[hits] = new Bubble(0, hits, currentC);
hits--;
}
In that case hits runs from 14 to 0 inclusive setting the corresponding entry in temp to a color 0 Bubble.
Set a break point on `hits--' in the first loop to confirm if it ever gets triggered.
I can't tell because I can how the state of this.myBoard[i] entering the function.

Related

2D array filling | ArrayIndexOutOfBoundsException error

good afternoon! hi all! 1st time posting
for my assignment we are filling arrays using arithmetic and nested for loops. i've done a complete filling of a 2D array before using prime numbers, although i think i'm messing up somewhere..
when doing the line int priorNum = arr[r-1][c]; (see full code below) i run into an exception. i am trying to overwrite other lines in my array with this new equation, but must i be stopped by this utmost unchivalrous java error.
the error: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
my array: int[][] arrayDimension = new int[10][6];
public static void populate2D (int[][] arr) {
//hardcode in values first :)
//and then peek up one row, but you can't go above the original row
arr[0][1] = 10;
arr[0][2] = 100;
arr[0][3] = 500;
arr[0][4] = 1000;
arr[0][5] = 5000;
int count = 0;
//for each row..
for (int r = 0; r < arr.length; r++) { //for each row
for ( int c = 0; c < arr[r].length; c++) { //for each column
arr[r][0] = count;
//never navigate out of bounds
//row 0 is where we're at.. how to populate further rows..?
int priorNum = arr[r-1][c];
int nextNum = priorNum * 2;
arr[r][c] = nextNum;
//can't look back .. SO go UP one.. which is r - 1 goes back one.. and then the length goes - 1
//when c is - peek UP a row < and enter last column.. ^
}
count++;
}
}
i left in some notes that i wrote if you can understand what i'm trying to go for :)
i can also offer this printArray method i wrote for any testing you'd like to try!
public static void print2DArray(int[][] arr) {
for ( int r = 0; r < arr.length; r++) {
for ( int c = 0; c < arr[r].length; c++) {
System.out.print(arr[r][c] + "\t");
}
System.out.println();
}
}
}
thank you for any replies / assistance! everyone here seems very nice, i could not find my type of question that deals with my answer so i felt bad about posting hehe
The problem I can see is that in the first iteration when int priorNum = arr[r-1][c]; gets executed, r = 0, as specified by your outer for loop.
So you are basically trying to access an element of your 2D array using a negative index, which will result in an ArrayIndexOutOfBoundException being thrown.
You could adopt an if statement that will handle the first iteration so that you will not access a prior index.
You could also look at the Array access section of the following article:
https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html
Hope this helped.

How can I decrease the brightness of a new image by 50 units in 2D arrays of String using if statement in Java?

import java.util.Arrays;
public class Combining {
public static void main(String[] args) {
int[][] imageData={{100,90,255,80,70,255,60,50},
{255,10,5,255,10,5,255,255},
{255,255,255,0,255,255,255,75},
{255,60,30,0,30,60,255,255}};
//First, we want to crop the image down to a 4x6 image, removing the right 2 columns. Declare and initialize a new 2D array of integers with 4 rows and 6 columns called `newImage`.
int[][] newImage = new int[4][6];
//Now that you have your empty image, use nested **for** loops to copy over the data from the original image to the new image, make sure not to include the cropped out columns.
for (int i = 0; i < imageData.length; i++) {
for (int j = 0; j < imageData[i].length - 2; j++) {
newImage[i][j] = imageData[i][j];
}
}
System.out.println(Arrays.deepToString(newImage));
//You want to decrease the brightness of the new image by 50 units. The way this works is that for every integer in the new 2D array, we will subtract the value by 50. Remember that the value range for the pixel is 0-255, so if the result tries to go below 0, just set it equal to 0.
if (imageData[i][j] - 50 < 0) {
newImage[i][j] = imageData[i][j] - 50;
} else {
newImage[i][j] = 0;
}
System.out.println(Arrays.deepToString(newImage));
}
}
Below is the question I have.
We want to decrease the brightness of the new image by 50 units. The way this works is that for every integer in the new 2D array, we will subtract the value by 50. Remember that the value range for the pixel is 0-255, so if the result tries to go below 0, just set it equal to 0.
Below is the hint to the question.
Remember to check if the value minus 50 is less than 0 when iterating through the elements of the new image: if(newImage[row][column]-50<0). If that condition is true, then set the element to equal 0 else subtract 50 from the element.
Below is code I have tried to solve the question.
//You want to decrease the brightness of the new image by 50 units. The way this works is that for every integer in the new 2D array, we will subtract the value by 50. Remember that the value range for the pixel is 0-255, so if the result tries to go below 0, just set it equal to 0.
if(imageData[i][j] - 50 < 0) {
newImage[i][j] = imageData[i][j] - 50;
} else {
newImage[i][j] = 0;
}
System.out.println(Arrays.deepToString(newImage));
}
}
I keep getting syntax error in the console that cannot find symbol i and j.
Combining.java:23: error: cannot find symbol
if(imageData[i][j] - 50 < 0) {
^
for the first part of your code
the for loop can be replaced with this
for (int i = 0; i < 4; i++) {
System.arraycopy(imageData[i], 0, newImage[i], 0, 4);
}
check the api for more detail about this method arraycopy
by the way your code will work but this is just another way
now for the issue
Combining.java:23: error: cannot find symbol
if(imageData[i][j] - 50 < 0) {
i and j in the for loop are only defined inside the loop body
local variable are defined and accessible only from where they defined so for example
int[][] newImage = new int[4][6];
for (int i = 0; i < 4; i++) {
System.arraycopy(imageData[i], 0, newImage[i], 0, 4); // only i defined here
}
\\here you can only access imageData and newImage but not i as i out of the scope
for local variable the scope determined by the { }
check this to get more details about variable scope
so either to define i and j outside the for loop like
int i, j = 0;
for (; i < imageData.length; i++) {
for (; j < imageData[i].length - 2; j++) {
newImage[i][j] = imageData[i][j];
}
}
or do the subtraction inside the for loop
for (int i = 0; i < imageData.length; i++) {
for (int j = 0; j < imageData[i].length - 2; j++) {
newImage[i][j] = imageData[i][j];
if (imageData[i][j] - 50 >= 0) {
newImage[i][j] = imageData[i][j] - 50;
} else {
newImage[i][j] = 0;
}
}
by the way the logic with your if is not right you should check the above version
also you can do it using that
newImage[i][j] -= 50;
newImage[i][j] = newImage[i][j] >= 0 ? newImage[i][j] : 0;

Weighted random numbers in 2D Array - Processing

I would like to fill a 3x3 2D array with values 1,2,3.
I need each number to appear for a given times.
For example:
1 to appear 2 times
2 to appear 4 times
3 to appear 3 times
What I need is to store this numbers to array in a random position.
For Example:
1,2,2
3,2,2
1,3,3
I already did this in a simple way using only 2 different numbers controlled by a counter. So I loop through the 2D array and applying random values of number 1 and number 2.
I'm checking if the value is 1 and add it in the counter and the same with number 2. if one of the counter exceeds the number I have set as the maximum appear times then it continues and applies the other value.
Is there any better approach to fill the 3 numbers in random array position?
See code below:
int [][] array = new int [3][3];
int counter1 =0;
int counter2 =0;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
array[i][j] = (int)random(1, 3); //1,2
if (arrray[i][j]==1) {
counter1++;
} else if (array[i][j] ==2) {
counter2++;
}
//if it is more than 5 times in the array put only the other value
if (counter1>5) {
array[i][j] = 2;
}
//if it is more than 4 times in the array put only the other value
else if (counter2>4) {
array[i][j] = 1;
}
}
}
I finally did this according to this discussion:
How can I generate a random number within a range but exclude some?, with 1D array for tesing, but it does not always works.
Please see attached code:
int []values = new int[28];
int counter1=0;
int counter2=0;
int counter3=0;
for (int i=0; i<values.length; i++) {
if (counter1==14) {
ex = append(ex, 5);
}
if (counter2==4) {
ex =append(ex, 6);
}
if (counter3==10) {
ex =append(ex, 7);
}
values[i] = getRandomWithExclusion(5, 8, ex);
if (values[i]==5) {
counter1++;
} else if (values[i] ==6) {
counter2++;
} else if (values[i] ==7) {
counter3++;
}
}
int getRandomWithExclusion(int start, int end, int []exclude) {
int rand = 0;
do {
rand = (int) random(start, end);
}
while (Arrays.binarySearch (exclude, rand) >= 0);
return rand;
}
I would like to fill the 1D array with values of 5,6 or 7. Each one a specific number. Number 5 can be added 14 times. Number 6 can be added 4 times. Number 7 can be added 10 times.
The above code works most of the times, however somethimes it does not. Please let me know if you have any ideas
This is the Octave/Matlab code for your problem.
n=3;
N=n*n;
count = [1 2; 2 4; 3 3];
if sum(count(:,2)) ~= N
error('invalid input');
end
m = zeros(n, n);
for i = 1:size(count,1)
for j = 1:count(i,2)
r = randi(N);
while m(r) ~= 0
r = randi(N);
end
m(r) = count(i,1);
end
end
disp(m);
Please note that when you address a 2D array using only one index, Matlab/Octave would use Column-major order.
There are a ton of ways to do this. Since you're using processing, one way is to create an IntList from all of the numbers you want to add to your array, shuffle it, and then add them to your array. Something like this:
IntList list = new IntList();
for(int i = 1; i <= 3; i++){ //add numbers 1 through 3
for(int j = 0; j < 3; j++){ add each 3 times
list.append(i);
}
}
list.shuffle();
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
array[i][j] = list.remove(0);
}
}
You could also go the other way: create an ArrayList of locations in your array, shuffle them, and then add your ints to those locations.

Checking rows of 2d ArrayList for specific values

I am trying to scan every row of a 2d array (100x100 sizes) and make sure that every row (and later column) will have only 1 instance of every integer 1 through 100. In the following code I am trying to make sure every row only has one instance of every integer 1 through 100, but obviously the syntax does not work. Is there any method that could push this through or what am I missing?
Thanks for any assistance
for(int i = 0; i<100; i++) {
for (int j=0; j<100 ; j++) {
if(2dARR.get(i).get(j).contains(1) && 2dArr.get(i).get(j).contains(2)(.....)) {
System.out.println("FK");
}
}
}
Dump it into a Set, check that the size of the Array and Set are Equal. If they aren't, there are duplicates. If you get past that test, run a loop through the array and check that all values are greater than 0 and less than 101 (1-100).
for(int i = 0; i<100; i++) {
Set<Integer> numbersInRow = new HashSet<Integer>();
for (int j=0; j<100 ; j++) {
int num = 2dARR.get(i).get(j);
if (num < 1 || num > 100) {
// out of bounds, handle error
}
else {
numbersInRow.add(num);
}
}
// At this point we have the set of numbers found in the row, all guaranteed to be >=1 and <= 100
if (numbersInRow.size() != 100) {
// at least one number appeared more than once
}
}

Logic Solving Algorithm for Sudoku (Java)

I decided to write a logic solving algorithm for my Sudoku application. What I wrote works for a limited amount of grid values, but then the recursion stops way too soon.
What my methods do:
addToThirdDimension(): A three dimensional array stores any possible values that can be put into the grid value at logicGrid[x][y]. This method refreshes the three dimensional array. It does this by testing values 1-9 in every grid index, and if it's valid, it adds that number to the array. If not, it sets that value to zero.
checkValues(): Checks how many possibilities are left in the three dimensional grid. It goes through the logicGrid and returns the number of non-zero values are in the grid.
checkSingleValue(int row, int col): Checks logicGrid[row][col] to see if there is one and only one value left in there (If there is one value left, it is the only possibility for the grid element at [row, col]). It returns the amount of non-zero values that are in that grid location.
getSingleValue(int row, int col): Returns the single number that's left in logicGrid[row][col]
immutableValues: A two dimensional boolean array that stores whether or not a specific grid element is immutable or not. If it is immutable, the solve method should not touch it.
public boolean solveWithLogic(){
addToThirdDimension();
if(checkValues() == 0){
return true;
}
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(!immutableValues[row][col]){
if(checkSingleValue(row, col) == 1){
sGrid[row][col] = getSingleValue(row, col);
setValues[row][col] = true;
addToThirdDimension();
}
}
}
}
if(checkValues() != 0){
solveWithLogic();
} else{
return true;
}
return false;
}
I cannot see where I am going wrong. After a certain number of tries, checkValues returns 0 even though there should be more possibilities. Here is the code for addToThirdDimension() as I am sure that if something is wrong, it is here.
sGrid is the main two-dimensional integer array that stores the values for the puzzle.
public void addToThirdDimension(){
logicGrid = new int[9][9][9];
for(int x = 0; x < 9; x++){
for(int y = 0; y < 9; y++){
for(int z = 0; z < 9; z++){
logicGrid[x][y][z] = z + 1;
}
}
}
int[][] temp1 = sGrid;
for(int row = 0; row < 9; row++){
for(int col = 0; col < 9; col++){
if(setValues[row][col]){
for(int i = 0; i < 9; i++){
logicGrid[row][col][i] = 0;
}
} else{
for(int i = 1; i <= 9; i++){
temp1[row][col] = i;
if(!isColumnValid(col, temp1) && !isRowValid(row, temp1) &&
!isQuadrantValid(row, col, temp1){
logicGrid[row][col][i-1] = 0;
}
}
}
temp1[row][col] = sGrid[row][col];
}
}
}
The code isn't too efficient at the moment. I want to get it working before I start minimizing solve times.
The first thing I would do is create a SudukoCell object that stores your possible values in it. Then create a SudukoBoard with a 2d array of SudukoCells. Also give it an array of SudukoAreas. One area for rows, one area for cols, and one area for blocks.
Add your suduko cells appropriately.
This will help you consolidate your legwork and prevent silly mistakes.
then every time you solve a number, you can go to the cells in each of its areas and remove the number you solved from them.

Categories