Traversing a 2D array matrix diagonally from bottom left to upper right - java

I have a 3x4 matrix represented by a 2D array:
. 0 1 2 3
0 a c f i
1 b e h k
2 d g j l
and my approach to traverse the diagonal slice was to treat each slice as a sum, like this:
a = (0+0) = 0
b,c = (0+1),(1+0) = 1
d,e,f = (0+2),(1+1),(2+0) = 2
g,h,i = (1+2),(2+1),(3+0) = 3
j, k = (2+2),(3+1) = 4
l = (3+2) = 5
However, my code right now prints it in the opposite way that I want it to, which is from upper right to bottom left.
Current Output is:
acbfedihgkjl
Desired Output is:
abcdefghijkl
for (int sum = 0; sum <= numRows + numColumns - 2; sum++) {
for (int i = 0; i < numRows; i++) {
int j = sum - i;
if ((i >= 0 && i < numRows) && (j >= 0 && j < numColumns)) {
System.out.print(array[i][j]);
}
}
}
Can somebody point me in the right direction on how to fix my code to get the output that I want?

While it isn't very pretty, I think this will do it:
int i = 0;
int j = 0;
while (true) {
System.out.println("" + array[i][j]);
--i;
++j;
if (i < 0) {
if (j == numCols)
break;
i = Math.min(j, numRows - 1);
j = Math.max(j - numCols + 2, 0);
} else if (j >= numCols) {
if (i == numRows - 2)
break;
i = numRows - 1;
j = Math.max(j + 2 - numCols + i, 0);
}
}

int i = 0;
int j = 0;
int n = 0;
int x = 3;
int y = 4;
int newSize = Math.max(x,y) * Math.max(x,y);
while(n < newSize){
if(i <= x && j <= y)
System.out.println(array[i][j]);
n++;
if(i == 0) {
i = n:
j = 0;
} else {
--i;
++j;
}
}

Related

SPOJ Prime Generator, getting TLE, but approached with the best I could. (JAVA)

The problem is to generate prime in between two interval, detail problem is given in this link. SPOJ Prime Generator.
Let me explain the magic numbers and the algorithm I followed.
I have used modified Sieve Eratosthenes algorithm (modified in sense because I used the basic idea.) for implementation.
Starting number of interval, m and End number of the interval n are <= 10^9 and the difference is <=10^5 (1 <= m <= n <= 1000000000, n-m<=100000)
There is no even prime number except 2, so I considered max m and n (10^9)/2
and sqrt(max number) is around 32000 (considering both odd and even), finally 32000/2= 16,000 is the size of odd numbers list input_aray.
Finally total number range is divided into 3 regiions.
m and n both >= 32000 in this case the size of the input_aray is (n-m+1)/2 from 16001 index of array, numbers between m and n is stored (only odd numbers).
m and n <32000 in this case size of input_aray is upto n/2.
m <32000 and n>32000 in this case size of input_aray is (n-32000+1)/2.
Boolean array bol of same size as input_aray is kept to track which number is visited so that two number can't be considered twice.
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
This loop choose n index from input_aray and check if there is any number in this array that is divisible, if so then same index of bol is initialized into false.
for (int k = j + flag; k <= 16000; k = k + flag)
This loop check for prime numbers upto 32000.
for (int k = 16001; k < input_aray.length; k++)
This one checks in between ** m and n** (when m&n >=32000)
*This is the fastest approach I could implement, but still get Time Limit Exceed. What could be the probable cause?
public static void main(String args[]){
Scanner take= new Scanner(System.in);
ArrayList<String> arrayList= new ArrayList<>();
int m,n;
int temp= take.nextInt();
take.nextLine();
if(temp>=0 && temp<=10){
for(int i=0;i<temp;i++) {
String temp1 = take.nextLine();
arrayList.add(temp1);
}
}
for(int i=0;i<arrayList.size();i++){
String[] temp_aray= arrayList.get(i).split(" ");
m= Integer.parseInt(temp_aray[0]);
n= Integer.parseInt(temp_aray[1]);
if(m>0 && n>0 && m<=10E8 && n<=10E8 && n-m<= 10E4 ) {
if (m >= 32000 && n >= 32000) {
//m & n > 32000
int start;
int[] input_aray = new int[16001 + ((n - m + 1) / 2) + 1];
boolean[] bol = new boolean[16001 + ((n - m + 1) / 2) + 1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < 16001; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
if (m % 2 == 0) {
start = m + 1;
} else {
start = m;
}
for (int j = 16001; j < input_aray.length; j++) {
input_aray[j] = start;
start += 2;
}
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
for (int k = j + flag; k <= 16000; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
for (int k = 16001; k < input_aray.length; k++) {
if (input_aray[k] % flag == 0) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 16001; j < bol.length; j++) {
if (bol[j] == true) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
if(m<32000 && n< 32000){
int[] input_aray = new int[(n/2)+1];
boolean[] bol = new boolean[(n/2)+1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < input_aray.length; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
for (int j = 1; j < Math.sqrt(n); j++) {
int flag = input_aray[j];
for (int k = j + flag; k<input_aray.length; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 0; j < bol.length; j++) {
if (bol[j] == true && input_aray[j] >=m && input_aray[j]<=n) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
if(m<32000 && n>32000){
int start;
int[] input_aray = new int[16001 + ((n - 32000 + 1) / 2) + 1];
boolean[] bol = new boolean[16001 + ((n - 32000 + 1) / 2) + 1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < 16001; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
start=32001;
for (int j = 16001; j < input_aray.length; j++) {
input_aray[j] = start;
start += 2;
}
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
for (int k = j + flag; k <= 16000; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
for (int k = 16001; k < input_aray.length; k++) {
if (input_aray[k] % flag == 0) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 0; j < bol.length; j++) {
if (bol[j] == true && input_aray[j]>=m && input_aray[j]<=n) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
}
}
}

Sudoku count subfield

I am currently working on a SudokuChecker I want to check the subfields [3x3] of the sudoku. The following code does this:
int[][] field = new field[9][9];
int wrongNumbers = 0;
for (int i = 0; i < 9; i += 3) {
for (int j = 0; j < 9; j += 3) {
// Check subfield by using an array
int arr[] = new int[10];
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
arr[field[i + k][j + l]]++;
}
}
for (int k = 1; k < arr.length; k++) {
wrongNumbers += arr[k] > 1 ? arr[k] - 1 : 0;
}
}
}
I want to know are there any improvements for the given code?
(I am not talking about making the 3, 9, etc. constant)
I found a very good answer in Codefights from thucnguyen:
boolean sudoku(int[][] grid) {
for (int i = 0; i <9; i++) {
int row = 0, col = 0, group = 0;
for (int j = 0; j <9; j++) {
// check for row i
row += grid[i][j];
// check for col i
col += grid[j][i];
// check for sub-grid i
group += grid[i / 3 * 3 + j / 3][i % 3 * 3 + j % 3];
}
if (row != 45 || col != 45 || group != 45) return false;
}
return true;
}

How to refactor this java code [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I have the below java method called solution, there are two large for loops, as you can see, the two for loops are very samilar, so I think it's possible to refactor the code by having a method like public int getElementSize(ArrayList<Integer> factor1, ArrayList<Integer> factor2) which does the work of the for loop, so I can just call the method twice with different parameters instead repeating the two for loop. But since these two for loops have different loop orders, one from head to tail, another one from tail to head, beside this, all other parts of the loop are the same, any ideas how to refactor this code?
class Solution {
public int solution(int[] A) {
ArrayList<Integer> factor1 = new ArrayList<Integer>();
ArrayList<Integer> factor2 = new ArrayList<Integer>();
int factor = 1;
int N = A.length;
while(factor * factor <= N){
if(N % factor == 0){
factor1.add(factor);
factor2.add(N / factor);
}
factor++;
}
for(int i = 1; i < factor2.size(); i++){
int blockSize = factor2.get(i);
int elementSize = factor1.get(i);
int peaks = 0;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
if(peaks == blockSize)
return blockSize;
}
for(int i = factor1.size() - 1; i >= 0; i--){
int blockSize = factor1.get(i);
int elementSize = factor2.get(i);
int peaks = 0;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
if(peaks == blockSize)
return blockSize;
}
return 0;
}
}
How about this?
Conditional operator, ? and : similar to, (these are called ternary operators and resolve at compile time to if else blocks)
if(condition) {
this();
} else {
that();
}
In the above, you can single line that as, (condition ? this() : that())
class Solution {
public int solution(int[] A) {
ArrayList<Integer> factor1 = new ArrayList<Integer>();
ArrayList<Integer> factor2 = new ArrayList<Integer>();
int factor = 1;
int N = A.length;
while(factor * factor <= N){
if(N % factor == 0){
factor1.add(factor);
factor2.add(N / factor);
}
factor++;
}
// let i = 0 to be factor2, i = 1 is factor 1
for(int i = 0; i < 2; i++) {
for(int x = (i == 0 ? 1 : factor1.size() - 1); (i == 0 ? x < factor2.size() : x >= 0); (i == 0 ? x++ : x--)){
int blockSize = (i == 0 ? factor2.get(x) : factor1.get(x));
int elementSize = (i == 0 ? factor1.get(x) : factor2.get(x));
int peaks = 0;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
if(peaks == blockSize)
return blockSize;
}
}
return 0;
}
}
You can refactor the code inside the the for loops to the new method inside move the two big for loops to the new method, in this way, the order of the two loops are still independent, basically it looks like below, the correctness needs to be verified, this is just one idea to not repeat:
class Solution {
public int solution(int[] A) {
ArrayList<Integer> factor1 = new ArrayList<Integer>();
ArrayList<Integer> factor2 = new ArrayList<Integer>();
int factor = 1;
int N = A.length;
while(factor * factor <= N){
if(N % factor == 0){
factor1.add(factor);
factor2.add(N / factor);
}
factor++;
}
for(int i = 1; i < factor2.size(); i++){
int blockSize = factor2.get(i);
int elementSize = factor1.get(i);
int peaks = getElementSize(A, blockSize, elementSize); //call the method
if(peaks == blockSize)
return blockSize;
}
for(int i = factor1.size() - 1; i >= 0; i--){
int blockSize = factor1.get(i);
int elementSize = factor2.get(i);
int peaks = getElementSize(A, blockSize, elementSize); //call the method
if(peaks == blockSize)
return blockSize;
}
return 0;
}
//this method include the code which was repeated inside the loops
public int getElementSize(int[] A, int blockSize, int elementSize){
int peaks = 0;
int N = A.length;
for(int j = 0; j < blockSize; j++){
boolean hasPeak = false;
for(int k = elementSize * j; k < elementSize * (j + 1); k++){
if(k > 0 && k < N - 1){
if(A[k] > A[k - 1] && A[k] > A[k + 1])
hasPeak = true;
}
}
if(!hasPeak)
break;
else
peaks++;
}
return peaks;
}
}

Insert a String of numbers into a matrix

I'm kind of stuck in this algorithm. I have this function below that gets a String and a matrix[n][m].
The String has up to n*m digits, and I need to insert them by reverse from the last digit to the last cell of the matrix, respectively, until I reach the first cell;
For example: the String='3' will be like that {[0][0],[0][3]}; the String='123' will be like that {[0][1],[2][3]}; and the String='2222' will be like that {[2][2],[2][2]};
The issue is: For the String '123' I get a matrix {[1][1],[1][1]}. It seems like only the first digit insert into the matrix.
stringToInteger(String correctBase, int [][] board)
{
int integerNum;
for(int i=correctBase.length()-1; i>=0; i--)
{
integerNum=correctBase.charAt(i)-'0';
for(int row=board.length-1; row>=0; row--)
for(int col=board[row].length-1; col>=0; col--)
board[row][col]=integerNum;
}
Try this:
stringToInteger(String correctBase, int [][] board)
{
int integerNum;
int row = board.length - 1;
int col = board[0].length - 1;
for(int i=correctBase.length()-1; i>=0; i--)
{
integerNum=correctBase.charAt(i)-'0';
board[row][col]=integerNum;
col--;
if(col < 0) {
col = board[0].length - 1;
row--;
}
}
...
}
Yes, or:
int i = correctBase.length();
for(int row=board.length-1; row>=0; row--)
for(int col=board[row].length-1; col>=0; col--)
board[row][col] = i > 0 ? correctBase.get(--i)-'0' : 0;
I would first check if the size of the string matches the size of the matrix. If it does not, then pad said string with zeroes. Then just parse the positions of the string and insert them into the matrix.
Try it like this.
public static void main(String[] args) {
//define size of matrix
int n = 2;
int m = 2;
String input = "3";
//if size of string is less than matrix size we append 0 to it
if (input.length() < n * m) {
int diff = n * m - input.length();
for (int i = 0; i < diff; i++)
input = "0" + input; //pad zeroes to the string
}
int board[][] = new int[n][m]; //declare matrix
//populate matrix
int stringPosition = 0; //position in the string starting from the left
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
board[i][j] =
Character.getNumericValue(input.charAt(stringPosition)); //transfrom char to int, then assign it to matrix
stringPosition++; //increment position
}
}
//display matrix
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
System.out.println("board[" + i + "][" + j + "] = " + board[i][j]);
}
}
}
It produces the desired results
input="3"
board[0][0] = 0
board[0][1] = 0
board[1][0] = 0
board[1][1] = 3
input="123"
board[0][0] = 0
board[0][1] = 1
board[1][0] = 2
board[1][1] = 3
input="2222"
board[0][0] = 2
board[0][1] = 2
board[1][0] = 2
board[1][1] = 2

Number Pyramid like Egyptian with decreasing numbers

Im working on a pyramid on Java. I did it with stars. But i want to do it with decreasing numbers. I'm using an input. Assume input is 5;
5
545
54345
5432345
543212345
My code is;
int size = 11;
for (int i = 1; i <= size; i=i+2) {
int spaceCount = (size - i)/2;
for(int j = 0; j< size; j++) {
if(j < spaceCount || j >= (size - spaceCount)) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
System.out.println();
}
I'm very glad to for your attention. Thanks a lot.
int size = 11;
for (int i = 1; i <= size; i=i+2) {
int spaceCount = (size - i)/2;
for(int j = 0; j< size; j++) {
if(j < spaceCount || j >= (size - spaceCount)) {
System.out.print(" ");
} else {
System.out.print(n);
}
}
System.out.println();
}
Something like this ?
But this only works for numbers of 1 - 9.
int h = 2;
String spacing = h == 1 ? "" : String.format("%" + (h - 1) + "s", "");
StringBuilder s = new StringBuilder(String.valueOf(h));
System.out.printf("%s%s\n", spacing, s);
for(int i = h; i > 1; --i){
System.out.print(spacing.substring(0, i - 2));
s.insert(s.length() / 2 + 1, String.valueOf(i - 1) + String.valueOf(i));
System.out.println(s.toString());
}

Categories

Resources