to output all elements of square matrix in a spiral - java

The task is following:
a square matrix A of order M is given. Starting with the element A0,0 and moving clockwise, you should output all its elements in a spiral: the first row, the last column, the last row in reverse order, the first column in reverse order, the remaining elements of the second row and so on.
public class Pres10Task8 {
public static void main(String[] args) {
int m =4;
int [][] a=new int [m][m];
Random rand = new Random();
for(int i =0;i<a.length;i++){
for(int j =0;j<a[i].length;j++){
a[i][j]=rand.nextInt(100);
System.out.print(a[i][j]+" ");
}
System.out.println();
}
for(int k=0;k<m/2+1;k++){
for(int j = k; j<m+1-k;j++){
System.out.println(a[k][j]);
}
int j =m+1-k;
for(int i=k+1;i<m+1-k;i++){
System.out.println(a[i][j]);
}
for(int j=m-k;j>k;j--){
j =k ;
System.out.println(a[i][j]);
}
for(int i =m-k;i>k+1;i-- ){
i =m+1-k;
System.out.println(a[i][j]);
}
}
}
}
Would you be so kind to look through my code and say what is wrong with it? How should I rewrite my code in order to get the right output?

You couldn't use a variable in your loop already exist before your method :
int j = m + 1 - k;
// ^--------------------------------------Already exist
for (int i = k + 1; i < m + 1 - k; i++) {
System.out.println(a[i][j]);
}
for (int j = m - k; j > k; j--) {
// ^---------You can't declare a variable already exist,
//you can just use it or initialize it
So instead use this without int j:
for (j = m - k; j > k; j--) {
Second
System.out.println(a[i][j]);
// ^-----The i is not exist so you have to
//create it and inisialize it so you can use it

You have made many mistakes as YCF_L mentioned in the answer and also After solving few of them I was still getting other errors. You can solve this problem by a simple logic that Divide Square Matrix into smaller squares and then follow the same pattern to print each of the squares.
For Example,
Suppose I have a matrix of order 5 then we can have 3 squares here for distinct dimensions.
1 1 1 1 1
1 2 2 2 1
1 2 3 2 1
1 2 2 2 1
1 1 1 1 1
Here each number represents that to which square the element belongs.So all outer elements belongs to first square then the next layer's elements belongs to second square and so on.
Now you have made your problem easier by dividing it into smaller sub-problems which can be solved in same way. Now you need to make logic of print the elements of each of the squares.
So for this, Consider the most outer square.
1 1 1 1 1 1 2 3 4 5
1 1 Thier Printing Order 16 6
1 1 ================> 15 7
1 1 14 8
1 1 1 1 1 13 12 11 10 9
So notice that we start from the first element and move into the same row into the right direction.
Then move in same column into down direction.
Then again in the same row in left direction.
At last in the same column but in the up direction.
After printing the outer square move to the inner square and do the same for each of the squares.
Code for the same:
import java.util.Scanner;
import java.util.Random;
public class Main {
public static void main(String[] args) {
int m =4;
int [][] a=new int [m][m];
Random rand = new Random();
for(int i =0;i<a.length;i++){
for(int j =0;j<a[i].length;j++){
a[i][j]=rand.nextInt(100);
System.out.print(a[i][j]+" ");
}
System.out.println();
}
int squares=m/2; //Calculating total number of squares
for(int i=0;i<squares;i++)
{
int low=i; //Set the dimension of the square
int high=m-i-1;
for(int j=low;j<=high;j++) //First Row --> (Right Direction)
System.out.println(a[low][j]);
for(int j=low+1;j<=high;j++) //Last Column --> (Down Direction)
System.out.println(a[j][high]);
for(int j=high-1;j>=low;j--) //Last Row --> (Left Direction)
System.out.println(a[high][j]);
for(int j=high-1;j>low;j--) //First Column --> (Up Direction)
System.out.println(a[j][low]);
}
if(m%2==1) //If Matrix is of odd order then print the middle element.
System.out.println(a[mid][mid]);
}
}

Why you use jagged array [][] instead of 2-dimensional [,] ???
May give a simple sample:
public void CountDiag(int size)
{
// initialize straight order
int[,] ar2 = new int[size, size];
int count = 0;
// initialize spiral way
int y = 0;
int x = 0;
int top = 0;
int bot = ar2.GetLength(0)-1;
int left = 0;
int right = ar2.GetLength(1)-1;
do
{
//topleft to right
for (; y < right; y++)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
right--;
//topright to bottom
for (; x < bot; x++)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
top++;
//botright to left
for (; y > left; y--)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
left++;
//botleft to top
for (; x > top; x--)
{
ar2[x, y] = count + 1;
count++;
}
ar2[x, y] = count + 1;
bot--;
} while (count < ar2.Length-1);
}
AND you print it out like this:
public void PrintArray(int[,] array)
{
int n = (array.GetLength(0) * array.GetLength(1) - 1).ToString().Length + 1; // for padding
for (int i = 0; i < array.GetLength(0); i++) // 0 - length rows
{
for (int j = 0; j < array.GetLength(1); j++) // 1 length columns
{
Console.Write(array[i, j].ToString().PadLeft(n, ' '));
}
Console.WriteLine();
}
Console.ReadLine();
}

Related

Minimum number of adjacent swaps of binary array

Given a binary array, find the number of minimum adjacent swaps needed to group 1's and 0's.
Example:
Input : 0,1,0,1 (array with 0 based index)
Swaps needed : 0,1,0,1 -> 0,0,1,1 (1 swap from index 1 to index 2)
Solution : 1
Exmaple:
Input : 1,0,1,0,0,0,0,1
Swaps needed :
1,0,1,0,0,0,0,1 -> 1,1,0,0,0,0,0,1 -> 1,1,0,0,0,0,1,0 -> 1,1,0,0,0,1,0,0 -> 1,1,0,0,1,0,0,0 -> 1,1,0,1,0,0,0,0 -> 1,1,1,0,0,0,0,0
Total 6 swaps so the solution is 6.
The 1's and 0's can be positioned at the beginning or end but they should be at a single place i.e. either begin or end.
I have come up with below logic for this requirement. I tried this in a hackerrank, it failed for a single hidden test case and gave timeout for 3 test cases as I have nested loops in my code.
static int countSwaps(List<Integer> list) {
int temp;
int swaps = 0;
int n = list.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1; j++) {
if ((list.get(j) == 0) && (list.get(j + 1) == 1)) {
temp = list.get(j);
list.set(j, list.get(j + 1));
list.set(j + 1, temp);
swaps++;
}
}
}
return swaps;
}
What is a better approach to solving this program?
I have already gone through this post Given an array of 0 and 1, find minimum no. of swaps to bring all 1s together (only adjacent swaps allowed) but the answers are not giving correct output.
Building on answer by Gene, fixing the compile error and supporting moving 1's to the left (to the beginning) or moving them to the right (to the end), aka moving 0's to the left:
static int countSwaps(int... a) {
int n0 = 0, i0 = 0, n1 = 0, i1 = 0;
for (int p = 0; p < a.length; ++p) {
if (a[p] == 0)
n0 += p - i0++; // No. of steps to move the 0 to the left
else
n1 += p - i1++; // No. of steps to move the 1 to the left
}
return Math.min(n0, n1); // Choose lowest no. of steps
}
Test
System.out.println(countSwaps(0,1,0,1));
System.out.println(countSwaps(1,0,1,0,0,0,0,1));
System.out.println(countSwaps(1,0,0,0,0,1,0,1));
Output
1
6
6
To move all 1's to the left, let p(i) be the position of i'th 1 from left to right. It ultimately needs to move to position i. This will need p(i) - i swaps. Just sum up this quantity for all i.
int countSwaps(int [] a) {
int n = 0, i = 0;
for (int p = 0; p < a.length; ++p)
if (a[p] == 1) {
n += p - i;
++i;
}
return n;
}
Moving to the right is symmetric. Do a similar computation and take the min.
Here is my solution (Java):
public static int minSwaps(int[] arr) {
int min_swaps1 = 0;
int zero_counts = 0;
int min_swaps2 = 0;
int one_counts = 0;
for (int j : arr) {
if (j == 0) {
zero_counts++;
min_swaps2 += one_counts;
} else {
one_counts++;
min_swaps1 += zero_counts;
}
}
return Math.min(min_swaps1, min_swaps2);
}

Making a border of numbers in descending order in matrix

I am trying to make a border around an empty matrix that is ascending and descending. I already have the top and left side which are ascending from 0 to 4, but I cannot get the right side and bottom side to go from 4 to 0. Here is the code of my for loops. I have tried about every variation to get it to work, but it either gives me an index out of bounds exception or just shows up as zeroes instead. I would greatly appreciate any feedback.
private static void fillBorder( int[][] matrix )
{
for (int r=0; r<matrix.length; ++r) // left side
{
matrix[r][0] = r;
}
for (int j=0 ; j<matrix.length; ++j) // top
{
matrix[0][j] = j;
}
for (int m=matrix.length; m>0; --m) // bottom
{
matrix[4][m] = m;
}
for (int s=matrix.length; s>0; --s) // right side
{
matrix[s][4] = s;
}
}
Here is also a picture of what the output is supposed to look like to give you a better idea of what it's supposed to be. picture of output
I think you can do this with a single for loop:
for (int i=0; i < matrix.length; ++i) {
matrix[0][i] = i;
matrix[i][0] = i;
matrix[matrix.length-1][matrix.length-1-i] = i;
matrix[matrix.length-1-i][matrix.length-1] = i;
}
This assumes that the matrix in fact is square (i.e. has the same number of rows and columns). If not, then my code would have to change, but then again so would your problem statement.
for (int r=0; r < matrix.length; ++r) {
for (int c=0; c < matrix.length; ++c) {
System.out.print(matrix[r][c] + " ");
}
System.out.println();
}
Output:
0 1 2 3 4
1 0 0 0 3
2 0 0 0 2
3 0 0 0 1
4 3 2 1 0
For your rows, you should be using matrix[0].length. The other thing is you should use the matrix dimension rather than hardcoding 4 into the code
private static void fillBorder( int[][] matrix )
{
for (int r=0; r<matrix.length; ++r) // left side
{
matrix[r][0] = r;
}
for (int j=0 ; j<matrix[0].length; ++j) // top
{
matrix[0][j] = j;
}
for (int m=matrix[0].length; m>0; --m) // bottom
{
matrix[matrix.length - 1][m] = m;
}
for (int s=matrix.length; s>0; --s) // right side
{
matrix[s][matrix[0].length - 1] = s;
}
}

java : Sum of Vertical elements in a triangle

I want to calculate the sum of all vertical elements in an triangle for example, if the triangle is
Ex : Triangle size is 5
1
2 2
5 2 2
2 0 5 8
8 7 9 4 5
Then the sum should be
Sum1 = 1+2+5+2+8 = 18 (Sum of vertical elements from the first column)
Sum2 = 2+2+0+7 = 11
Sum3 = 2+5+9 = 16
Sum4 = 8+4= 12
Sum5 = 5 = 5
Note : The triangle size will vary, also the elements will be random.
Program I wrote, but it's only calculating the first row how do i calculate and store the 2nd, 3rd and upto the last ?
public class fsdhs
{
public static void main(String args[])
{
int arr[]={1,2,2,5,2,2,2,0,5,8,8,7,9,4,5};
int x,y,count=0,size=5,sum=0;
boolean flag=false;
for(x=0;x<size;x++)
{
for(y=0;y<=x;y++)
{
if(flag==false)
{
sum=sum+arr[count];
flag=true;
}
System.out.print(arr[count]+" ");
count++;
}
System.out.print("\n");
flag=false;
}
System.out.print("\nSum1="+sum);
}
}
You can simplify your code and calculate col sums using the following formula to get index of array by index of i-th row in triangle and j-th column (j<=i, zero-based):
index = i*(i+1)/2 + j
For example, in given triangle at row i=3, column j=2 value is 5, so
index = 3*4/2 + 2 = 8, arr[8] is also 5
A more intuitive approach may be to use a multidimensional jagged array to store the triangle data. This way you can reason over the coordinates directly without needing to calculate row based offsets:
int arr[][]={{1},{2,2},{5,2,2},{2,0,5,8},{8,7,9,4,5}};
int size=5;
for(int x=0; x < size; x++)
{
int sum = 0;
for(int y=x; y < size; y++)
{
sum += arr[y][x];
}
System.out.println("Column " + x + " Sum=" + sum + "\n");
}
You just need to be wary of the uneven row sizes of the jagged array
IdeOne Demo
int SIZE = 5; // The size of your triangle
int arr[]={1,2,5,2,8,2,2,0,7,2,5,9,8,4,5}; // Array of triangle items
int[] sums = new int[SIZE];
for (int i = 0; i < arr.length; i += SIZE, SIZE--) {
for(int j = i; j < i + SIZE; j++) {
sums[sums.length - SIZE] += arr[j];
}
}
// Show items
for (int i = 0; i < sums.length; i++) {
System.out.println("item " + i + ": " + sums[i]);
}

Mirrored Triangle generation in java

I happened to appear for a test and got the following as question. I am unable to figure out how to proceed. The scenario is to write a java program that prints the following with respective N. If suppose N=3, it must have 2*N rows and output must be,
1
2*3
4*5*6
4*5*6
2*3
1
Output must consist only numbers and asterisk. N varies between 0 to 100. Also, given
public static void main(String[] args){
int rows=2;
mirrorTriangle(rows);
}
public void mirrorTriangle(int n){
//Logic
}
I don't understand why is that rows declared as 2 if rows are supposed to be varying with N. Please explain the logic.
Please find the solution to your problem, with explanation comments.
public static void main(String[] args) throws Exception
{
// initialize n
int n = 4;
// initialize x to 1 from where our printing will start.
int x = 1;
/* We will store our generated numbers in an array.
* For example, the array after we generate
* the numbers would look like:
* [1,0,0,
2,3,0,
4,5,6,
4,5,6,
2,3,0,
1,0,0]
*
* When n = 3, there are going to be 3*2 i.e, n*2 rows.
* in our case 6 rows.
* visualize with the above values.
* The first n/2 rows will be the numbers we print,
* the next n/2 will be the mirror image of the first n/2 rows.
* no. of columns in each row will be equal to n, in our example:3
*/
int arr[][] = new int[n*2][n];
/*
* Start populating the matrix
* Each row will contain number of elements eaual to the row number,
* so 1st row -> 1 element, 2nd - > 2,.. and so on.
*/
for(int row=0;row<n;row++)
{
int col = 0;
while(col < row+1)
{
arr[row][col] = arr[n*2-row-1][col] = x++;
col++;
}
}
/*
* Now our task is just to read out the array.
* The tricky part is adding the astricks.
* We notice that row1 will have 1-1 asticks, row2 -> 2-1 astricks ,.. and so on.
* So in between the numbers while reading out,
* for each row we maintain the number of astricks.
*/
for(int i=0;i<arr.length;i++)
{
StringBuilder build = new StringBuilder();
for(int j=0;j<arr[i].length;j++)
{
if(arr[i][j] > 0)
{
build.append((arr[i][j])).append("*");
}
}
System.out.print(build.delete(build.length()-1,build.length()).toString());
System.out.println();
}
}
o:p for n=4:
1
2*3
4*5*6
7*8*9*10
7*8*9*10
4*5*6
2*3
1
def N = 3
def i = 0
def j = 0
int[][] numbers = new int[N][]
// Generate, print, and store numbers
while( i < numbers.length ){
numbers[i] = new int[i+1]
j = 0
while( j < numbers[i].length ){
numbers[i][j] = j+1
++j
print j
}
println ""
i++
}
// Print them again, in reverse order
i = numbers.length - 1
while( i >= 0 ){
j = 0
while( j < numbers[i].length ){
print numbers[i][j]
j++
}
println ""
i--
}
Output:
1
12
123
123
12
1
The code is pretty self-explanatory. You need just N rows but print 2N because, wait for it ... symmetry. If you have 6 rows, first 3 are new while the other 3 are just mirrored images so why waste the memory space when you can just print them again?
Is there an explicit requirement for recursion? It is implied by the structure of the problem not mentioned anywhere.
int rows=2 is an example probably, for the purposes of the problem you can't do anything 'smart' like using pointers ...
I will also assume that you are not permitted to use values '> 100' so that you can overload the meaning of the n value - same goes for 2's complement.
If you allow for looping, as a substitute for recursion you can generate the triangle without having to save state outside of the stack:
public static void main(String[] args){
int rows=3;
mirrorTriangle(rows);
}
public static void mirrorTriangle(int n){
for (int i = 0 ; i < n + 1 ; i++) {
renderLine(i);
}
for (int i = n ; i > 0 ; i--) {
renderLine(i);
}
}
private static void renderLine(int n) {
int j = n * (n - 1) / 2 + 1;
int k = j + n;
while (j < k) {
System.out.print(j);
j++;
if (j < k) System.out.print('*');
}
System.out.println();
}
Try this fresh code:
public class String4 {
public static void main(String[] args) {
int rows = 3;
mirrorTriangle(rows);
}
private static void mirrorTriangle(int rows) {
for(int i=1;i<=rows;i++)
{
for(int j=1;j<=i;j++)
{
System.out.print(i);
if(j>0&&j<i)
System.out.print("*");
}
System.out.println();
}
for(int k=rows;k>0;k--)
{
for(int l=1;l<=k;l++)
{
System.out.print(k);
if(l>0&&l<k)
System.out.print("*");
}
System.out.println();
}
}
}
Output:
1
2*2
3*3*3
3*3*3
2*2
1
I think this is a better and simple solution than the chosen one.
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter limit");
int limit = s.nextInt();
int start[] = new int[limit];
int v = 1;
for (int i=1; i<=limit; i++) {
start[i-1] = v;
for (int j=1; j<=i; j++) {
System.out.print(v++);
if(j==i)
continue;
System.out.print("*");
}
System.out.print("\n");
}
for (int i=limit-1; i>=0; i--) {
v=start[i];
for (int j=i; j>=0; j--) {
System.out.print(v++);
if(j==0)
continue;
System.out.print("*");
}
System.out.print("\n");
}
}

Filling in the main diagonals in a 2D array

I am trying to write a code that fills in the 2 main diagonals in an NxN matrix, for example:
if N=5 (which is entered through command line), we would have a 5x5 matrix filled with zeros and the diagonals would have 2s filled in, like:
2 0 0 0 2
0 2 0 2 0
0 0 2 0 0
0 2 0 2 0
2 0 0 0 2
I wrote a code for an all-zero table, but i can't figure our how to fill in the diagonals.
Looking at the case of 5x5 i would have to fill in the matrix at the following indices:
#1 (0,0) (0,n-1)
#2 (1,1) (1,n-2)
#3 (2,2) (2,n-3)
#4 (3,1) (3, n-2)
#5 (4,0) (4,n-1)
However, since N can be any number, i assume that first i have to find the middle row, after which i have to decrement the indices in the reverse order.
I am learning Java for 2 weeks only and this one is pretty hard.
My code for a zero-filled table is this:
public static void main (String[] args){
int n = Integer.parseInt(args[0]);
System.out.println(n);
int[][] table = new int[n][];
for (int i = 0; i < n; i++) {
table[i] = new int[i + 1];
for (int j = 0; j <= i; j++) {
table[i][j] = (0);
}
} System.out.print(Arrays.deepToString(table));
}
Obviously, this is very far from what i need to achieve, and i am not sure if it's entirely right. I would really appreciate some help.
Try this,
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args){
int n = 5;
System.out.println(n);
int[][] table = new int[n][];
for (int i = 0; i < n; i++) {
table[i] = new int[n];
for (int j = 0; j < n; j++) {
if(i==j || n-i == j+1){
table[i][j] = table[i][n-i-1] = 2;
}
else{
table[i][j] = 0;
}
System.out.print(table[i][j]);
}
System.out.println();
}
}
}
To fill one diagonal, we just have to count from i==0 to i==size-1 and fill in (i,i) each time.
for(int i=0; i<size; i++) {
table[i][i] = 2;
}
The other diagonal is only slightly harder:
for(int i=0; i<size; i++) {
table[i][some calculation involving i and size] = 2;
}
You should be able to work out what the calculation is.
You can do it in two loops - but you can also combine filling both diagonals into one loop.
You could also amend your nested loops that create the array, to handle the cells on the diagonals as you encounter them there.
#inside the loop
if( a condition indicating that the cell is on a diagonal) {
table[i][j] = 2;
} else {
table[i][j] = 0;
}
Write down the coordinates of the cells on the diagonals, and you should quickly see what the condition is.

Categories