For my summer Java class, I'm working on a program that detects whether the elements in an array are a magic square. I'm not entirely sure how to properly iterate through the array to be able to calculate the total of the separate columns and rows to determine if the array is a magic square. We were given the code for the sum of the down diagonal, but I'm unsure how to approach the up diagonal, rows and columns. Here is a snippet of my code so far.
public class MagicSqaure
{
public static void main(String[] args)
{
int[][] array =
{
{2, 7, 6},
{9, 5, 1},
{4, 3, 8}
};
public static int getSumOfDownDiagonal(int[][] array)
{
int total = 0;
for (int i = 0; i < array.length; i++)
{
total += array[i][i];
}
return total;
}
Since it is a class, I can only provide help on how to accomplish traversing through the rows, columns and up diagonal, but providing **no code at all*. It's up to you to do the right implementation, otherwise you're not learning but copying/pasting/becoming a zombie coder.
To traverse each row, go through the elements of your array of arrays like this:
total += array[i][j];
Where i won't change but j changes.
To traverse each column, go through the elements of your array of arrays like this:
total += array[i][j];
Where i changes but j won't change.
To traverse the up diagonal, go through the elements of your array of arrays like this:
total += array[i][j];
Where i starts at the last possible index of the array of arrays and j starts at the first index of the array of arrays.
Whenever I need to derive equations for certain behaviors, I just write a few of the answers out manually then look for patterns. First let's assume this is how we access items in the array:
column
0 1 2
--------
0 | 2 7 6
row 1 | 9 5 1
2 | 4 3 8
(Using array[column][row])
Now let's get the indices for the columns:
column 0 = {2, 9, 4} = array[0][0], array[0][1], array[0][2]
column 1 = {7, 5, 3} = array[1][0], array[1][1], array[1][2]
And here are the rows:
row 0 = {2, 7, 6} = array[0][0], array[1][0], array[2][0]
row 1 = {9, 5, 1} = array[0][1], array[1][1], array[2][1]
And here's the other diagonal:
3x3 array = {4, 5, 6} = array[0][2], array[1][1], array[2][0]
4x4 array = array[0][3], array[1][2], array[2][1], array[3][0]
Notice any patterns? For the diagonal, we start at array[0][array.length - 1] and end at array[array.length - 1][0]. This means our loop would be as follows:
int total = 0;
for (int i = 0; i < array.length; i++)
{
total += array[i][array.length - 1 - i];
}
return total;
And to sum a column, it'd be:
int total = 0;
for (int i = 0; i < array.length; i++)
{
total += array[column_index][i];
}
return total;
And for rows:
int total = 0;
for (int i = 0; i < array.length; i++)
{
total += array[i][row_index];
}
return total;
EDIT: In response to downvotes and comments, I have modified the magic square code to work with row-major conventions. Oh wait, no I didn't since the code would be identical. Anyway, this is how you do it.
Related
I am trying to create a program that allows me to create a grid using a 2D array and nested for loop.
The problem is that when I run the program numbers do not form a table, they instead are printed out in a vertical column.
I first set up the array with 3 rows, each having arbitrary values. I then use a nested for loop where the first loop is meant to create the rows for which the loop will run, and the second loop is meant to create the columns.
package nestedLoops;
public class Trial_1 {
public static void main(String[] args) {
int[][] grid = {
{1, 2, 3, 4, 5},
{1, 2, 3, 4},
{1, 2, 3, 4, 5}
};
for(int i=0; i<grid.length; i++ ) {
for(int j=0; j<grid[i].length; j++) {
System.out.println(grid[i][j]);
}
}
}
}
However when I run the above code I get this output:
1
2
3
4
5
1
2
3
4
1
2
3
4
5
I think you need something like that:
for (int[] ints : grid) {
for (int anInt : ints) {
System.out.print(anInt);
}
System.out.println();
}
In the second loop you need to print 'anInt' and to wrap a line you need to add a line break between the loops.
You have to advance the output to the new line after printing each row.
For that, you need to a System.out.println(); statement after the nested loop.
In the nested loop you need to use System.out.print(); (not println) for printing the numbers of every row. And you also need to add a delimiter (white space, tabulation, etc.) between the numbers inside the row, or else they will get jumbled like that 12345.
int[][] grid = {{1, 2, 3}, {11, 22, 33}};
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
System.out.print(grid[i][j] + "\t");
}
System.out.println();
}
Output
1 2 3
11 22 33
I have two arrays and I am trying to assign the values of one array, i.e. arrayOne[0] should be equal to the corresponding index in arrayTwo[0].
I am trying to do this using a forloop so that it loops through the the index of one array assigning the values sequentially.
so far I have:
for (int a =0; a< arrayOne.length; ++) {
// this sets the an int that loops through the value of the arrays(both arrayOne and arrayTwo are the same length)
I am lost however after this how to create the for loop which assigns index 0 = 0 and then incrementally step through this.
I know this is a very basic question but I am, as my name suggests, struggling to learn coding.
I am lost however after this how to create the for loop which assigns index 0 = 0 and then incrementally step through this.
There are many ways to copy arrays. But since you specifically asked for a for loop solution, just create a new array of the same size and use a for loop as shown to index them.
int [] a = {1,2,3,4,5,6,7};
int [] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i]; // this copies element a[i] to b[i] where i is the index.
}
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
Prints
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
For example I have array with length n=3:
for(int i = 0; i < n; i++) {
array[i] = i;
}
So the cases should be:
1. 0
2. 1
3. 2
4. 0 1
5. 0 2
6. 1 2
7. 0 1 2
So the number of cases should be 7 for n = 3.
In my code:
int n = 3;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = i;
}
int sum = 0;
for (int i = 0; i < n; i++) {
System.out.println(array[i] + " ");
sum++;
for (int j = i; j < n; j++) {
System.out.print(array[j] + " ");
}
System.out.println();
sum++;
}
System.out.println("sum = " + sum);
Output is:
0
0 1 2
1
1 2
2
2
sum = 6
The number 2 is two times so it is wrong and sum is actually = 5. And I don't get cases
4. 0 1
and
5. 0 2
How to count all possible cases?
Sets, not arrays
The first important observance is that you are not using fixed length arrays here but sets of different lengths.
Take a look at your example. You allow
0
1
2
0, 1
0, 2
1, 2
which are not all of size 3.
Also you don't differentiate between
0, 1
1, 0
so order doesn't matter, like in sets.
Power set
That's why you're actually describing power sets here. For the example set {0, 1, 2} its power set is defined as
P({0, 1, 2}) = {
{}, // empty set
{0},
{1},
{2},
{0, 1},
{0, 2},
{1, 2},
{0, 1, 2}
}
Fortunately there exists an easy closed formula for their size. If n is the size of the input set the size of the power set is
2^n
But they also count the empty set, so you will need to -1 if you don't want that:
2^n - 1
Solution
Thus in Java you could write
int Set<Integer> input = ...
int size = (int) Math.pow(2, input.size()) - 1;
and that's all, you don't need to build the contents manually.
But if you're curious and want to build them, take a look at questions like Obtaining a powerset of a set in Java. It's an implementation of the recursive formula shown at Wikipedia.
So, totally inefficient but also working:
int Set<Integer> input = ...
// Build the power-set using the method from linked question
Set<Set<Integer>> power = powerSet(input);
int size = power.size() - 1;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Right now I'm trying to write a function that takes an array and an integer n, and gives a list of each size n combination (so a list of int arrays). I am able to write it using n nested loops, but this only works for a specific size of subset. I can't figure out how to generalize it to work for any size of combination. I think I need to use recursion?
This is the code for all combinations of 3 elements, and I need an algorithm for any number of elements.
import java.util.List;
import java.util.ArrayList;
public class combinatorics{
public static void main(String[] args) {
List<int[]> list = new ArrayList<int[]>();
int[] arr = {1,2,3,4,5};
combinations3(arr,list);
listToString(list);
}
static void combinations3(int[] arr, List<int[]> list){
for(int i = 0; i<arr.length-2; i++)
for(int j = i+1; j<arr.length-1; j++)
for(int k = j+1; k<arr.length; k++)
list.add(new int[]{arr[i],arr[j],arr[k]});
}
private static void listToString(List<int[]> list){
for(int i = 0; i<list.size(); i++){ //iterate through list
for(int j : list.get(i)){ //iterate through array
System.out.printf("%d ",j);
}
System.out.print("\n");
}
}
}
This is a well-studied problem of generating all k-subsets, or k-combinations, which can be easily done without recursion.
The idea is to have array of size k keeping sequence of indices of elements from the input array (which are numbers from 0 to n - 1) in increasing order. (Subset then can be created by taking items by these indices from the initial array.) So we need to generate all such index sequences.
First index sequence will be [0, 1, 2, ... , k - 1], on the second step it switches to [0, 1, 2,..., k], then to [0, 1, 2, ... k + 1] and so on. The last possible sequence will be [n - k, n - k + 1, ..., n - 1].
On each step, algorithm looks for the closest to the end item which can be incremented, increments it and fills up items right to that item.
To illustrate, consider n = 7 and k = 3. First index sequence is [0, 1, 2], then [0, 1, 3] and so on... At some point we have [0, 5, 6]:
[0, 5, 6] <-- scan from the end: "6" cannot be incremented, "5" also, but "0" can be
[1, ?, ?] <-- "0" -> "1"
[1, 2, 3] <-- fill up remaining elements
next iteration:
[1, 2, 3] <-- "3" can be incremented
[1, 2, 4] <-- "3" -> "4"
Thus, [0, 5, 6] is followed by [1, 2, 3], then goes [1, 2, 4] etc.
Code:
int[] input = {10, 20, 30, 40, 50}; // input array
int k = 3; // sequence length
List<int[]> subsets = new ArrayList<>();
int[] s = new int[k]; // here we'll keep indices
// pointing to elements in input array
if (k <= input.length) {
// first index sequence: 0, 1, 2, ...
for (int i = 0; (s[i] = i) < k - 1; i++);
subsets.add(getSubset(input, s));
for(;;) {
int i;
// find position of item that can be incremented
for (i = k - 1; i >= 0 && s[i] == input.length - k + i; i--);
if (i < 0) {
break;
}
s[i]++; // increment this item
for (++i; i < k; i++) { // fill up remaining items
s[i] = s[i - 1] + 1;
}
subsets.add(getSubset(input, s));
}
}
// generate actual subset by index sequence
int[] getSubset(int[] input, int[] subset) {
int[] result = new int[subset.length];
for (int i = 0; i < subset.length; i++)
result[i] = input[subset[i]];
return result;
}
If I understood your problem correctly, this article seems to point to what you're trying to do.
To quote from the article:
Method 1 (Fix Elements and Recur)
We create a temporary array ‘data[]’ which stores all outputs one by
one. The idea is to start from first index (index = 0) in data[], one
by one fix elements at this index and recur for remaining indexes. Let
the input array be {1, 2, 3, 4, 5} and r be 3. We first fix 1 at index
0 in data[], then recur for remaining indexes, then we fix 2 at index
0 and recur. Finally, we fix 3 and recur for remaining indexes. When
number of elements in data[] becomes equal to r (size of a
combination), we print data[].
Method 2 (Include and Exclude every element)
Like the above method, We create a temporary array data[]. The idea
here is similar to Subset Sum Problem. We one by one consider every
element of input array, and recur for two cases:
The element is included in current combination (We put the element in data[] and increment next available index in data[])
The element is excluded in current combination (We do not put the element and do not change index)
When number of elements in data[] become equal to r (size of a
combination), we print it.
I've been tackling this one problem and currently having a lack of ideas of how to parse a numerical data divided into small snippets of data squares into two dimensional array. Data is arranged in rectangle like form (Supposedly similar as it would be in a file/text file). Data would look like like in the picture provided below, numerical values can be completely random so they do not matter. I would need to parse all possible squares (red, blue and green highlighted ones are an example) that can be found within that rectangle into an array of square objects .
The problem I am facing is figuring out the way to read all possible square combinations within this rectangle and properly writing them to the console. (I am sure if I could read and print them properly to the console I won't be having too much trouble storing that data either.). I've been thinking of how to do it in several ways, but unfortunately all those attempts and ponderings didn't click in my mind properly. I am not sure if my thoughts would be of any help to you, but here is a snippet of my miserable attempt at figuring this parsing problem. I am trying to print to the console at least 3x3 squares that could be found within the rectangle (matrix/2D array - you name it). It'd be great if anyone could help me figure out how to read and print all possible squares that can be found within that rectangle.
EDIT: Since I can't post images due to website restrictions, I am leaving the link:
Data Image
EDIT2: I also noticed that square highlighted in green colour is incorrect due to not being actually a square, please ignore that and excuse me for inconvenience and possible confusion.
public static void main(String[] args){
int[][] rectangle = {
{4, 9, 6, 2, 6},
{3, 5, 1, 6, 4},
{8, 1, 5, 6, 2},
{1, 1, 6, 2, 2}
};
int m = 5; // row length
int n = 4; // column length
int min = 3; // minimum square row/column length for iteration
int start = 0;
int step = 0;
for (int x = 0; x < n-1; x++){
for(int y = start; y < m-1; y++){
if (y < min){ // no idea how to make this part work
System.out.print(rectangle[x][y] + " ");
step++;
}
if(Math.pow(min, 2) == step && x != n - 1){
// once here save the square, initialize new one;
System.out.println("");
step = 0;
start++;
y = start;
x++;
}
// all squares have been read in x-th column, moving more to the right
if( x == n - 1 && y == min - 1 && x != y){
y = start + 1;
x = 0;
}
}
System.out.println(" ");
}
}
This algorithm works as follows:
determine all points that can be the upper-left-hand-corners of a square in a given rectengle
for each of these determine all possible sizes, so that the complete square is in the rectange
do thins with the new-found squares (in this case print two oppisite corners)
int[][] rectangle = {
{4, 9, 6, 2, 6},
{3, 5, 1, 6, 4},
{8, 1, 5, 6, 2},
{1, 1, 6, 2, 2}
};
int m = 5; // row length
int n = 4; // column length
int min = 3; // minimum square row/column length for iteration
//Take all possible upper-left-hand-corners
for(int row = 0; row <= n - min; row++){
for(int column = 0; column <= m - min; column++){
//Determine all possible square sizes from that corner
for(int size = min; size <= n - row && size <= m - column; size++){
//This will print the upper-left-hand-corner
//and the lower-right-hand-corner as (x|y)
//Place here anything that you want to do with the squares
System.out.println("(" + column + "|" + row + ") to ("
+ (column+size-1) + "|" + (row+size-1) + "), size: " + size);
}
}
}
One note on n and m: You might not want to hardcode the values for the dimensions of the rectangle. Instead you might want to use:
int m = rectangle[0].length;
int n = rectange.length;