I am having trouble with dividing a 2D array into boxes, like in Sudoku. I have an array of squares in my board object, and I want to divide them into 2x3 or 3x3 boxes, The box objects have a 1D array to keep track of the squares.
k is the box number, in a 9x9 sudoku, the boxes will be numbered 0 through 8.
int l = 0;
for(int i=k*a; i<k*a+a;i++){
for(int j=k*b;j<k*b+b;j++){
narray[l]=brd.getSquare(i,j);
brd.getSquare(i,j).setBox(this);
l++;
}
This gets the first box right, but goes off after that. I've been thinking about this for hours now, and I can't seem to wrap my head around it. Does anyone have a neat trick for this?
So, I'll assume the boxes are numbered like this:
012
345
678
(and the boxes consist of 3x3 cells each)
If i and j are x and y coordinates, you'll need to translate the above to coordinates. Something like:
0 1 2 3 4 5 6 7 8
x 0 1 2 0 1 2 0 1 2
y 0 0 0 1 1 1 2 2 2
So x = k%3 and y = k/3.
In the actual grid x and y has to start from 0, 3 and 6 rather than 0, 1 and 2, so just multiply by 3.
So something like this should do it: (changes depending on which coordinate is x and which is y)
int size = 3;
int l = 0;
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
int x = i + k % size * size;
int y = j + k / size * size;
narray[l] = brd.getSquare(x, y);
brd.getSquare(x, y).setBox(this);
l++;
}
}
If you want to use a single number to index a 2D array, use the mod / divide functions.
row = index / row_size;
col = index % col_size;
Your index should be in the range 0 to (row_size*col_size -1)
So it sounds like you just want to get the box row and box column.
int boxsize = 3;
int h = 9; //height
inh w = 9; //width
for (int r =0;r<h;r++){
for (int c=0;c<w;c++){
int br = r/boxsize;
int bc = c/boxsize;
int index = br*h + c;
narray[index]=brd.getSquare(br,bc);
System.out.println("box row =" + br +" box column =" + bc);
}
}
Related
Recently, I had encountered an interesting programming puzzle which had some good twist and turn mentioned in the puzzle. Below the question which amazed me, I simply eager to know if any relevant solution probably in java is feasible for below scenario.
Problem statement:
There is a grid of dimension m*n, initially, a bacterium is present at the bottom left cell(m-1,0) of the grid with all the other cells empty. After every second, each bacteria in the grid divides itself and increases the bacteria count int the adjacent(horizontal,vertical and diagonal) cells by 1 and dies.
How many bacteria are present at the bottom right cell(m-1,n-1) after n-1 seconds?
I had taken references from
https://www.codechef.com/problems/BGH17
but failed to submit the solution
Below is the image for more insite of problem
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
public class BacteriaProblem {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Number of Rows: ");
int m = sc.nextInt();
System.out.println("Number of Columns: ");
int n = sc.nextInt();
int[][] input = new int[m][n];
input[m - 1][0] = 1;
Stack<String> stack = new Stack<>();
stack.push(m - 1 + "~" + 0);
reproduce(stack, input, n - 1);
System.out.println("Value at Bottom Right corner after n-1 secs: " + input[m - 1][n - 1]);
}
private static void reproduce(Stack<String> stack, int[][] input, int times) {
//exit condition
if (times < 1) {
return;
}
//bacteria after splitting
List<String> children = new ArrayList<>();
//reproduce all existing bacteria
while (!stack.isEmpty()) {
String[] coordinates = stack.pop().split("~");
int x = Integer.parseInt(coordinates[0]);
int y = Integer.parseInt(coordinates[1]);
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) continue;
split(input, x + i, y + j, children);
}
}
input[x][y]--;
}
//add all children to stack
for (String coord : children) {
stack.push(coord);
}
//reduce times by 1
reproduce(stack, input, times - 1);
}
private static void split(int[][] input, int x, int y, List<String> children) {
int m = input.length;
int n = input[0].length;
if (x >= 0 && x < m && y >= 0 && y < n) {
input[x][y]++;
children.add(x + "~" + y);
}
}
}
Well, I was asked this question in an Online Hackerrank test and couldn't solve it at that time.
I did later try to code it and here's the soln in C++,
long countBacteriasAtBottomRight(int m, int n){
long grid[m][n];
// Set all to 0, and only bottom left to 1
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
grid[i][j] = 0;
}
}
grid[m-1][0] = 1;
// Start the cycle, do it for (n-1) times
int time = n-1;
vector<long> toBeUpdated;
while (time--){
cout << "\n\nTime: " << time;
for (int i=0; i<m; i++){
for (int j=0; j<n; j++){
while (grid[i][j] > 0){
grid[i][j]--;
// upper left
if (i > 0 && j > 0){
toBeUpdated.push_back(i-1);
toBeUpdated.push_back(j-1);
}
// upper
if (i > 0){
toBeUpdated.push_back(i-1);
toBeUpdated.push_back(j);
}
// upper right
if (i > 0 && j < n-1){
toBeUpdated.push_back(i-1);
toBeUpdated.push_back(j+1);
}
// left
if (j > 0){
toBeUpdated.push_back(i);
toBeUpdated.push_back(j-1);
}
// bottom left
if (i < m-1 && j > 0){
toBeUpdated.push_back(i+1);
toBeUpdated.push_back(j-1);
}
// bottom
if (i < m-1){
toBeUpdated.push_back(i+1);
toBeUpdated.push_back(j);
}
// bottom right
if (i < m-1 && j < n-1){
toBeUpdated.push_back(i+1);
toBeUpdated.push_back(j+1);
}
// right
if (j < n-1){
toBeUpdated.push_back(i);
toBeUpdated.push_back(j+1);
}
};
}
}
// Update all other cells
for (int k=0; k<toBeUpdated.size(); k+=2){
grid[toBeUpdated[k]][toBeUpdated[k+1]]++;
}
for (int i=0; i<m; i++){
cout << endl;
for (int j=0; j<n; j++)
cout << grid[i][j] << " ";
}
// Clear the temp vector
toBeUpdated.clear();
};
return grid[m-1][n-1];
}
The starting situation only has a value in the left-most column 0. We need to know the situation in the right-most column n-1 after time n-1. This means that we only have to look at each column once: column x at time x. What happens to column x after time x is no longer important. So we go from left to right, adding up the cells from the previous column:
1
1 8
1 7 35
1 6 27 104
1 5 20 70 230
1 4 14 44 133 392
1 3 9 25 69 189 518
1 2 5 12 30 76 196 512
1 1 2 4 9 21 51 127 323 ...
You will also notice that the result for the last cell is only influenced by two cells in the previous column, and three in the one before that, so to calculate the end result for e.g. the case n=9, you only need to calculate the values in this triangle:
1
1 4 14
1 3 9 25 69
1 2 5 12 30 76 196
1 1 2 4 9 21 51 127 323
However high the grid is, we only ever have to go up n/2 (rounded up) rows. So the total number of sums we have to calculate is n2/4, or n×m if m < n/2.
Also note that we don't have to store all these values at once, because we go column by column from left to right. So we only need a one-dimensional array of size n/2, and the current values in it are transformed like this (e.g. going from column 4 to 5 in the example above):
[4, 5, 3, 1] (0) -> 0 + 5 - 0 = 5
[9, 5, 3, 1] (5) -> 9 + 3 - 5 = 7
[9,12, 3, 1] (7) -> 12 + 1 - 7 = 6
[9,12, 9, 1] (6) -> 9 + 0 - 6 = 3
[9,12, 9, 4] (3) -> 4 + 0 - 3 = 1
[9,12, 9, 4, 1] (1) (additional value is always 1)
where we iterate over the values from left to right, add up the value to the left and right of the current element, subtract a temporary variable which is initialized to 0, store the result in a temporary variable, and add it to the current element.
So the theoretical time complexity is O(n2) or O(n.m) and the space complexity is O(n) or O(m), whichever is smaller. In real terms, the number of steps is n2/4 and the required space is n/2.
I don't speak Java, but here's a simple JavaScript code snippet which should easily translate:
function bacteria(m, n) {
var sum = [1];
for (var col = 1; col < n; col++) {
var temp = 0;
var height = Math.min(col + 1, n - col, m);
if (height > sum.length) sum.push(0);
for (var row = 0; row < height; row++) {
var left = row > 0 ? sum[row - 1] : 0;
var right = row < sum.length - 1 ? sum[row + 1] : 0;
temp = left + right - temp;
sum[row] += temp;
}
}
return sum[0];
}
document.write(bacteria(9, 9));
I was trying to create the simpliest matrix - 2d array and I have trouble with my code, it is kind of working, but not correctly.
Code:
int result = 0;
int[][] matrix = new int[2][2];
for(int rows = 0; rows < matrix.length; rows++)
for(int cols = 0; cols < matrix[rows].length; cols++)
matrix[rows][cols] = (rows + cols);
System.out.println("matrix is: "+matrix);
result = matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0];
System.out.println("Result is: "+result);
Output:
matrix is: [[I#1db9742
Result is: -1
I had this one:
int result = 0;
char[][] matrix= new char[2][2];
for(int rows = 0; rows < 2; rows++)
for(int cols = 0; cols < 2; cols++)
matrix[rows][cols] = (char)('1' + rows * 2 + cols);
for(int rows = 0; rows < 2; rows++)
for(int cols = 0; cols < 2; cols++)
System.out.println("matrix is: "+matrix[rows][cols]);
result = matrix[0][0]*matrix[1][1]-matrix[0][1]*matrix[1][0];
System.out.println("Result is: "+result);
Output:
matrix is: 1
matrix is: 2
matrix is: 3
matrix is: 4
Result is: -2
But I do not want char, I want integer (because what if work with big matrix calculations later) and I do not understand tis part:
('1' + rows * 2 + cols)
because I copied it from some other code. How to get the first one to work like second and what is that part in brackets (why writen like that)? Thanks in advance!
I got nice stuff with 1 2 3 4 that is what I wanted, but I also need explanation for what that "('1' + rows * 2 + cols)" means. I want to get 1 2 3 4 for matrix 2D array, and then 1*4-2*3 for result. Maybe '1' is to start from 1, not from 0 in loop and write from 1 in array. I found it in some other code, not my solution, first one is mine and not working properly. I added:
for(int cols = 0; cols < matrix[rows].length; cols++)
as you suggested.
*I rewrote it to english.
Sorry for language confusion.
I don’t understand why I get characters instead of 2D array when printing matrix after loop, before calculating.
I think the result is correct.
This is your matrix :
| 0 1 |
| 1 2 |
And this is what you do : 0 * 2 - 1 * 1
and the good answer is = -1.
The code for what you want is :
int i = 1;
for(int redovi = 0; redovi < matrica.length; redovi++)
for(int kolone = 0; kolone < matrica.length; kolone++)
matrica[redovi][kolone] = i;
++i;
So we will get a matrix like this one :
|1 2|
|3 4|
And so the good answer for what you want. If I well understood.
You should look closer on what you write into matrix. The first looks like:
0 1
1 2
and second:
'1' '2'
'3' '4'
So both determinants are calculated almost as you expect. You can change one line in the first code to this:
matrix[rows][cols] = (1 + rows*matrix[rows].length + cols);
So that your matrix is 1234.
By the way, using char[][] worked because any char can be represented as a number that is an index in character map.
I also need explanation for what that "('1' + rows * 2 + cols)" means
Character '1' is 49th in character map, '2' is 50th and so on. Try to compile this, for example:
System.out.println((int)'1');
So "('1' + rows * 2 + cols)" generates a matrix that can be represented as int[][]:
49 50
51 52
I have to output my 2D Array from left to right on even rows, and from right to left on odd rows. I've done that and that isn't the problem. The problem is I am getting really confused when I try to access an element inside the 2D array because now the odd rows are reversed.
Here is my current output with the output being from left to right then right to left:
0.5 0.62 0.35 0.6 0.5
0.13 0.25 0.25 0.62 0.45
0.65 0.85 0.2 0.2 0.8
Here is the output without making any changes to the output:
0.5 0.62 0.35 0.6 0.5
0.45 0.62 0.25 0.25 0.13
0.65 0.85 0.2 0.2 0.8
I need to get the average of each 2 X 2, and then find out which is the weakest. I have done that, however the math doesn't seem to work out, and I am assuming it is because the elements on odd rows are reversed.
Here is my current output for finding the weakest:
0.5
0.45999999999999996
0.3625
0.3625
0.3625
0.3625
0.22499999999999998
0.22499999999999998
Weakest begins at (1, 2) with an average strength of 0.22499999999999998
Here is what the correct output should have an average strength of 0.3175:
Weakest begins at (1, 2) with an average strength of 0.3175
Finally here is my code for making each odd row output from right to left:
int k = 0;
cd = new double[3][5];
for(int i = 0; i<cd.length;i++)
for(int j=0; j<cd[i].length;j++,k++)
cd[i][j]=gridArr[k];
for(int i = 0; i < cd.length; i++){
if(i%2==0)
for(int j = 0; j < cd[i].length; j++)
System.out.print(String.format("%-10s" ,cd[i][j]));
else
for(int j = cd[i].length -1; j >= 0; j--)
System.out.print(String.format("%-10s" ,cd[i][j]));
System.out.println();
}
Here is the code to find the weakest 2 X 2:
double weakest = getAverage(0, 0, 0, 0);
int weakestRow = 0;
int weakestCol = 0;
for(int row = 0; row < cd.length-1; row++){
for(int col = 0; col < cd[0].length-1;col++){
if(weakest > getAverage(row, row+1, col, col+1)) {
weakest = getAverage(row, row+1, col, col+1);
weakestRow = row;
weakestCol = col;
} System.out.println(weakest);
}
}
System.out.println("\nWeakest begins at "
+"("+weakestRow+", "+weakestCol+") with an average strength of "
+weakest);
}
Any ideas? I've looked over this for hours and can't wrap my head around it...
Edit: getAverage is:
double first = cd[startRow][startCol];
double second = cd[endRow][startCol];
double third = cd[startRow][endCol];
double fourth = cd[endRow][endCol];
return (first+second+third+fourth)/4;
It's because your program is find the average of the square on the original array, not the one where you reverse the order of the odd rows.
Displaying the array has no effect.
What you shoudl do, is call your getWeakest method on an array where the odd rows has been reversed.
oddRowReversedArray = new double[3][5];
for(int i = 0; i < cd.length; i++){
if(i%2==0)
oddRowReversedArray[i] = cd[i]
else
for(int j = cd[i].length -1; j >= 0; j--)
oddRowReversedArray[i][j] = cd[i][cd.length -1 -j]
}
and then call getWeakest of this array.
Pasted below is a program to print Pascal's triangle. The way to compute any given position's value is to add up the numbers to the position's right and left in the preceding row. For instance, to compute the middle number in the third row, you add 1 and 1. the sides of the triangle are always 1 because you only add the number to the upper left or the upper right (there being no second number on the other side).
int pascal[][]=new int[50][50]; int j;
for(int i=0;i<m;i++)
{
pascal[i][i]=1;
for(j=1;j<i;j++)
{
pascal[i][j]=pascal[i-1][j-1]+pascal[i-1][j];
}
for(int n=1;n<=m-i;n++)
{
System.out.print(" ");
}
for(int k=1;k<=i;k++)
{
System.out.print(pascal[i][k]);
System.out.print(" ");
}
System.out.println(" ");
}
Is there any way to accomplish this without using arrays?
I'm trying this combination without arrays:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
You can easily compute it using Combination.
You can compute combination as:
|n| = (n!) / ((n-k)!*k!)
|k|
So if you want to print the image above you would start as:
int size = 5;
for(int i = 0; i < size; i++){
for(int k = 0; k < (size - i)/2; k++)
System.out.print(" "); // print the intendation
for(int j = 0; j <= i; j++){
System.out.print(combination(i,j));
}
System.out.println("");
}
DISCLAIMER: THIS IS PART OF A HOMEWORK ASSIGNMENT
So i have created an array with the the count of each letter. It would look something like this:
Array charCount
charCount[0] = 10
charCount[1] = 6
charCount[2] = 4
I know that 0 = a, 1 = b etc.
Now I want to print these results to a graphic representation using asteriks. For example:
*
*
*
*
*
**
**
**
***
***
***
ABC
I found this rather difficult and don't really understand how to do this.
- I've made a function to check the max value of my array.
for (int i = 0; i < charCount.length; i++) {
if (letterCount[i] > maxInt) {
maxInt = charCount[i];
}
}
Then I've made a for loop to check if there are any matches.
My next part of code is:
for (int i = 0; i < letterCount.length; i++ ) {
for (int j = 0; j <= maxInt; j++) {
if (letterCount[i] == maxInt) {
System.out.println("*");
} if (letterCount[i] == maxInt - j ) {
System.out.println("*");
} if (letterCount[i] != maxInt ) {
System.out.println(" ");
}
}
But here it where I got stuck.
How do i print asteriks all the way down and next to each other? Should I work with spaces?
How do i know when to stop printing? Does my maxInt - j makes sense?
Can someone point my in the right direction?
I have to come up with a solution using for loops and arrays, So i cant use any fancy methods yet :)
Thank you :)
Imagine you wanna draw this like a bar graph to a grid, which has coordinates, similar to what you did in school with x and y coordinates.
To stay with your example, each y coordinate represents the index of your array, e.g. the specific letter, where the x - coordinate the amount.
Since those numbers may get quite large, it's, like you saw, not best practice to map +1 on the x-coordinate to +1 letter.
Therefore you need to determine the size of your diagram, let's say it shall be 10 letters wide:
y <- 10
^
a|**********
b|**********
c|**********
-------------> x
12345 ...10
Now it's important that the occurences of the letters relative to each other are represented correctly by those *-bars, that means the letter which occurs the most could be shown with a bar exactly as long as you draw the x-coordinate, in this case 10.
Lets use this as an example dataset
0 := 10
1 := 6
2 := 4
3 := 14
If the x-coordinate is 10 * long, the amount from entry 3 (highest in the array) is 14 and needs to be 10 * long. With this information you can calculate the factor by dividing 10(x-length) / 14(biggest amount) ~= 0.71 (the factor)
This factor you apply to all the numbers to get number of stars to draw.
Here as an example in java:
int xLength = 10;
int[] charCount = new int[5];
charCount[0] = 10;
charCount[1] = 4;
charCount[2] = 7;
charCount[3] = 14;
charCount[4] = 1;
// determine the biggest value:
int biggest = 0;
for(int n:charCount) {
if(n>biggest)
biggest = n;
}
System.out.println("Biggest no: " + biggest);
double factor = (double)xLength / (double)biggest;
System.out.println("Using factor: " + factor);
for(int i = 0; i < charCount.length; i++) {
System.out.print("no " + i + ":");
for(int j = 0; j < charCount[i] * factor; j++) {
System.out.print("*");
}
System.out.println();
}
This will output:
Biggest no: 14
Using factor: 0.7142857142857143
no 0:********
no 1:***
no 2:*****
no 3:**********
no 4:*
EDIT:
If you want to print the bars vertically (on the y-choordinate), or turn it any other way, store the bars in a grid, for example with a String[][] array, where arr[2][3] would be y-coordinate 2 and x-coordinate 3. Then you can calculate with the factor above and the maximum height of the chart whether or not a specific point / coordinate should be filled with a "*" or a " " (nothing):
// make a grid to draw the chart
// the height is the the number we defined as maximum height (xLength)
// and the width is one column for every char (charCount.length):
String[][] grid = new String[charCount.length][xLength];
// initialize the grid with spaces:
for(int x = 0; x < grid.length; x++) {
for(int y = 0; y < grid[x].length; y++) {
grid[x][y] = " ";
}
}
// We will go through the grid column by column:
for(int x = 0; x < grid.length; x++) {
// this will be called once for every char
// so just replace spaces in the grid in this column
// by "*" if it's a row (value of y) <= the amount
// of chars times the factor
for(int y = 0; y < grid[x].length; y++) {
if(y <= charCount[x] * factor) {
grid[x][y] = "*";
}
}
}
// print the grid row by row (think of it upside down, (0,0) is the upper left point
// so we start with the last (the no of elements in the array minus 1, counting from 0)
System.out.println("^");
for(int y = grid[0].length - 1; y >= 0; y--) {
System.out.print("|");
for(int x = 0; x < grid.length; x++) {
System.out.print(grid[x][y]);
}
// finish the line:
System.out.println();
}
// draw the bottom line:
System.out.println("------->");
System.out.println(" abcde");
Added this code just below the code from above, the output will be:
Biggest no: 14
Using factor: 0.7142857142857143
no 0:********
no 1:***
no 2:*****
no 3:**********
no 4:*
^
| *
| *
|* *
|* *
|* **
|* **
|* **
|****
|****
|*****
------->
abcde
If you want to put the amounts left to the y-bar, divide the row number by the factor.
If you want to use the absolute values without scaling up or down (which would fill the screen pretty fast for big numbers), just set the 'xLength' (height of the grid) to the biggest number in the input array.