Is there a way to combine incrementing and decrementing for loops? - java

int j = 0;
for (int i = 1; i < 4; i++)
{
if ((columnIndex + i) > 6 || this.isWinningCondition(columnIndex, i, j, colSlot, isRed))
{
break;
}
else
{
pieces++;
}
}
for (int i = -1; i > -4; i--)
{
if ((columnIndex + i) < 0 || this.isWinningCondition(columnIndex, i, j, colSlot, isRed))
{
break;
}
else
{
pieces++;
}
}
Basically, it is apart of a Connect4 program that searches for three in a row on the left and right side of a specific column (in this case, it is searching for horizontal wins), hence the incrementing (for the right side) and the decrementing (for the left side) for loops. Is there a way I can combine these for loops into one, so I don't have to repeat myself?

If your MaxValue ( 4 )is always the same for both for loop, you can always do :
for( int i = 1; i < 4; ++i)
{
//verify i version 1
int i2 = i * -1;
// verify i2 version 2
}

Try the mixed for loop.
for(int i = 0, j = 4; i <= 4 && j >=0; i ++, j --)
{
System.out.println(i + " " + j);
}
Output:
0 4
1 3
2 2
3 1
4 0

Related

How to print a 2D array in java

Hello so am trying to create a 2D array of int with random number of rows and columns and a random starting and ending points using java to apply the A* algorithm on it.
When i add {S} and {E} to define the tow points and print it there are numbers outside of the 2D array printed.
`Random rand = new Random();
int min = 2, max = 10;
// a random number of rows and columns
int a = (int)(Math.random() * (max - min + 1)) + min;
// the location of the starting point.
int row_start = rand.nextInt(a);
int col_start = rand.nextInt(a);
// the location of the ending point.
int row_end = rand.nextInt(a);
int col_end = rand.nextInt(a);
int [][] M = new int [a][a];
public void create() {
//empty: 0; grass: 1; sand: 2; water: 3; wall: 4.
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
M[i][j] = rand.nextInt(5);
}
}
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
System.out.print(" " +M[i][j] + "\t");
if(row_start == i && col_start == j) {
System.out.print("{S}" + "\t");
}
if(row_end == i && col_end == j) {
System.out.print("{E}" + "\t");
}
}
System.out.print("\n");
}
}`
the output looks like this:
1 0 4 0
2 {S} 1 2 2
4 4 {E} 0 3
2 0 3 3
the 2 and 3 shouldn't appear there.
The problem is that you always print m[i][j].
What you need is to only print m[i][j] when i and j are not S and E positions. When i and j are S and E positions, print S or E. Otherwise, print m[i][j].
if(row_start == i && col_start == j) {
System.out.print("{S}" + "\t");
} else if(row_end == i && col_end == j) {
System.out.print("{E}" + "\t");
} else {
System.out.print(" " +M[i][j] + "\t");
}

How should I reconfigure the arrow "->" to not print when done with with my pathing?

I'm trying to create an optimal path to collect as many 1's as I can but after I execute my code, I still have an arrow pointing to nothing as there are no more places to go. How would I remove the arrow at the end of the code?
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner s1 = new Scanner(System.in);
int n = s1.nextInt();
int m = s1.nextInt();
int mat[][] = new int[n][m];
for (int i = 0; i < mat.length; i++){
for (int j = 0; j < mat[0].length; j++){
mat[i][j] = s1.nextInt();
}
}
int path[][] = new int[n][m];
for (int i = 0; i < path.length; i++){
Arrays.fill(path[i], -1);
}
int maxCoins = util(0, 0, mat, path);
System.out.println("Max coins:" + maxCoins);
int row = 0, column = 0;
System.out.print("Path:");
while(row < mat.length && column < mat[0].length){
System.out.print("(" + (row + 1) + "," + (column + 1) + ")");
System.out.print("->");
if(row < n - 1 && column < m - 1){
int down = path[row + 1][column];
int right = path[row][column + 1];
if(down > right){
row += 1;
continue;
}
else if (right > down){
column += 1;
continue;
}
else{
row += 1;
continue;
}
}
if(row + 1 < n){
row += 1;
}
else{
column += 1;
}
}
}
private static int util(int row,int column,int mat[][], int path[][]){
if(row >= mat.length || column >= mat[0].length){
return 0;
}
if(path[row][column]!= -1){
return path[row][column];
}
int right = util(row, column + 1, mat,path);
int down = util(row + 1, column, mat,path);
path[row][column]=Math.max(right, down);
if(mat[row][column] == 1){
path[row][column] += 1;
}
return path[row][column];
}
}
My current input looks like:
5 6
0 0 0 0 1 0
0 1 0 1 0 0
0 0 0 1 0 1
0 0 1 0 0 1
1 0 0 0 1 0
And output is:
Max coins:5
Path:(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(3,6)->(4,6)->(5,6)->
I am just trying to remove the one at the end but unsure where to insert my code:
System.out.print("->");
Cleanest way would be using a StringJoiner.
You can use it as follows
StringJoiner joiner = new StringJoiner("->");
joiner.add("a");
joiner.add("b");
System.out.println(joiner); //prints a->b - you can use toString if you want to return a joined String
You can also define a prefix and suffix for your joined String.
Or if you are familiar with Streams, there is Collectors.joining("->") available.
Three solutions that come to mind:
Add another check inside the loop, and put your sysout -> thingy after that check.
Usually code would generate some kind of list or similar data about the results and return it. It's a lot simpler to print lists, because you know the length etc.
Another common solution is to use StringBuilder and correct it before generating the output with toString()
You could just do something like this:
if (!(row == mat.length - 1 && column == mat[0].length - 1)) {
System.out.print("->");
}
Or a little cleaner:
if (arrowIsNotAtTheEnd(mat, row, column)) {
System.out.print("->");
}
// ...
private static boolean arrowIsNotAtTheEnd(int[][] mat, int row, int column) {
return !(row == mat.length - 1 && column == mat[0].length - 1);
}
For java 8 and above, the String class already has a convenient join method.
CharSequence[] path=new CharSequence[]{
"(1,1)","(2,1)","(2,2)","(2,3)","(2,4)","(3,4)","(3,5)","(3,6)","(4,6)","(5,6)"};
String output=String.join("->",path);
System.out.println(output);
//output: (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(3,6)->(4,6)->(5,6)

Difference between writing ++i in the condition of a while loop and incrementing i inside the while loop

I am writing the code as shown at the bottom of this question.
For the while loop part, I thought the following two codes are just the same
first one
while (lIndex < rIndex && height[++lIndex] <= left) {
ans += (left - height[lIndex]);
}
second one
while (lIndex < rIndex && height[lIndex + 1] <= left) {
ans += (left - height[lIndex + 1]);
lIndex++;
}
However, when I run the second one on system,
There is an error of Time Limit Exceeding.
Could someone explain the reason of this problem?
Thanks for reading my question.
Original code:
public int trap(int[] height) {
if (height.length < 3) return 0;
int ans = 0;
int lIndex = 0;
int rIndex = height.length - 1;
// Find the first wall on each side
while (lIndex < rIndex && height[lIndex] <= height[lIndex + 1]) lIndex++;
while (lIndex < rIndex && height[rIndex] <= height[rIndex - 1]) rIndex--;
while (lIndex < rIndex) {
int left = height[lIndex];
int right = height[rIndex];
if (left <= right) {
while (lIndex < rIndex && height[++lIndex] <= left) {
ans += (left - height[lIndex]);
}
}
else {
while (lIndex < rIndex && height[--rIndex] <= right) {
ans += right - height[rIndex];
}
}
}
return ans;
}
In the first example, lIndex is incremented even when evaluation of the condition ends up with it being false. In other words, if the while loop body is executed n times, lIndex will be incremented n + 1 times.
In the second example, lIndex is only incremented with the rest of the body. So if the while loop body is executed n times, lIndex will be incremented n times.
Here's a very simple example of both, showing the difference:
public class Test {
public static void main(String[] args) {
int i = 0;
while (++i < 3) {
System.out.println("First loop iteration");
}
System.out.println("Value of i afterwards: " + i);
int j = 0;
while (j + 1 < 3) {
System.out.println("Second loop iteration");
j++;
}
System.out.println("Value of j afterwards: " + j);
}
}
Output:
First loop iteration
First loop iteration
Value of i afterwards: 3
Second loop iteration
Second loop iteration
Value of j afterwards: 2
So both loops execute the body twice, but they end up with different counter values.

Get all sequences of 1 and 0

I'm trying to reach following sequences of 1 and 0 for a three input system:
000
001
010
...
...
My current code didn't make it :-
for (int i = 0; i < possibleCombinations; i++) {
for (j = 0 ; j < 3; j++) {
if (j < 2 ){
k = j;
}
System.out.print(k + " ");
}
System.out.println();
}
How i can reach above result?
One line:
for (int i = 0; i < 8; i++) {
System.out.println(((i>>2)%2)+""+((i>>1)%2)+""+(i%2));
}
You can generalize this for n-channels of course.
int numChannels=3;
for (int i = 0; i < 2<<numChannels; i++) {
for(int j=numChannels-1; j>=0;j--){
System.out.print((i>>j)%2);
}
System.out.println();
}
Think it about using the periodicity of the occurence of zeroes and ones (first channel has pattern 00001111.., second 0011.., third 01..).
You can use bitmasks for this:
void generateCombinations(int n) {
for(int i = 0; i < (1 << n); i++) {
for(int j = n - 1; j >= 0; j--) {
if((i & (1 << j)) != 0) {
System.out.print(1);
} else {
System.out.print(0);
}
}
System.out.println();
}
}
So for n = 3 you will have 2 ^ n = 8 combinations. That's why the first for is 1 << n, this is the same as 2 ^ n.
For every number you check whether it's bits and print them.
(i & (1 << j)) != 0 - this checks if a bit is 1 or 0 on position j.
We have these situations:
n=2; -> 00,01,10,11
n=3;->000,001,010,011,100,101,110,111.
....
The algorithm is to just enumerate all numbers till 2^n - 1 in binary. For instance , n=2 :
0 in binary will be 00
1 in binary will be 01
2 in binary will be 10
3 in binary will be 11
For converting one integer number to binary string, you should use Integer.toBinaryString method.
Code:
static String print_binary(int n)
{
String binaryString=Integer.toBinaryString(n);
String additional=new String(new char[n-binaryString.length()]).replace("\0", "0");
if(binaryString.length() < n)
binaryString+=additional;
return binaryString;
}
static void Main(String args[]){
int possibleCombinations = 1<<LENGTH, i;
for(i = 0; i< possibleCombinations; i++)
System.out.println(print_binary(i));
}

Recursion with two increments

I am trying to create a recursion function that allows me to "simulate" a double for loop. Something similar to
Iterative:
for(int i = 0; i < list.length; i++) {
for(int x = i; x < list.length; x++) {
//handle logic here
}
}
Recursive:
public int solve(int start_index, int end_index) {
if(start_index >= array.length) { return 0; }
if(end_index >= array.length - 1) { solve(start_index + 1, 0); return 0; }
return solve(start_index, end_index + 1);
}
But it doesn't seem to return results similar to I think it should. Can any one help me out? Appreciate it!
Lets say your operation is a sum of an integer array. That's the iterative version:
for (int i = 0; i < array.length; i++)
for (int x = i; x < array.length; x++)
sum1 += array[x];
The recursive version will be something like:
public int solve(int x, int i, int end)
{
if(i == end)
return array[x];
else if(x == end)
return array[x] + solve(i + 1, i + 1, end);
else
return array[x] + solve(x + 1, i, end);
}
We would call it with sum2 = solve(0, 0, array.length-1);
The semantics of the variables i and x is the same on both the versions for better understanding.
In the end sum1 will be the same as sum2.
This should work (Note I am simulating similar behavior):
public class temp {
// This will be the method to simulate the double for loop you had
// listed in your question.
static void iterate(int index, int sub_index, int end_index) {
if (index < end_index){
if (sub_index < end_index ){
System.out.println(index + " " + sub_index );
iterate(index, sub_index + 1 , end_index);
}else {
iterate(index + 1, index+1 , end_index) ;
}
}
}
public static void main(String[] args){
// Simulate the usual double for loop
System.out.println("Double for loop");
for (int i = 0 ; i < 3 ; i++){
for (int j = i ; j < 3 ; j++){
System.out.println(i + " " + j);
}
}
// Simulate the double for loop through recursion
System.out.println("Double for loop through recursion");
iterate(0,0,3);
}
}
and the output will be:
Double for loop
0 0
0 1
0 2
1 1
1 2
2 2
Double for loop through recursion
0 0
0 1
0 2
1 1
1 2
2 2

Categories