how to write n-level embeded loop with java - java

Given M integers (N1, N2, Nm), I want to write a N-level embedded loop like following :
for (int a = 0; a < N1; a++)
for (int b = 0; b < N2; b++)
for (int c = 0; c < N3; c++)
....
for (int m = 0; m < Nm; m++)
operation
Since M is a variable, I cannot write fixed number level for-loop. What tricks could help ?

No need for recursion. Instead, think of each iterator as a digit in a number. When you increment the number, you increment the last digit, and if it exceeds the limit (normally 10), it's set to 0, and the digit to the left of it is increased, repeating the overflow logic.
In this case, each "digit" is an independent counter, each with their own "limit", i.e. the value of the given Nx. If you store those limit values in an array, and keep the counters in a same-size array, the logic is fairly simple.
Here is an example of an optimized version, that uses a label to exit directly from a nested loop:
int[] n = { 3, 4, 5 }; // m = 3: N1 = 3, N2 = 4, N3 = 5
int[] i = new int[n.length]; // All "digits" are 0
LOOP: for (;;) {
// operation using i[] here, e.g.
System.out.println(Arrays.toString(i));
// Process "digits" from last to first
for (int j = i.length - 1; ; j--) {
if (j < 0) // Exit main loop if first "digit" overflowed
break LOOP;
if (++i[j] < n[j]) // Increment "digit", and if not overflowed:
break; // exit digit-loop, i.e. loop back to process
i[j] = 0; // Reset "digit" to 0, then process next (to left) "digit"
}
}
Output
[0, 0, 0]
[0, 0, 1]
[0, 0, 2]
[0, 0, 3]
[0, 0, 4]
[0, 1, 0]
[0, 1, 1]
[0, 1, 2]
[0, 1, 3]
[0, 1, 4]
[0, 2, 0]
[0, 2, 1]
[0, 2, 2]
[0, 2, 3]
[0, 2, 4]
[0, 3, 0]
[0, 3, 1]
[0, 3, 2]
[0, 3, 3]
[0, 3, 4]
[1, 0, 0]
[1, 0, 1]
[1, 0, 2]
[1, 0, 3]
[1, 0, 4]
[1, 1, 0]
[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
[1, 1, 4]
[1, 2, 0]
[1, 2, 1]
[1, 2, 2]
[1, 2, 3]
[1, 2, 4]
[1, 3, 0]
[1, 3, 1]
[1, 3, 2]
[1, 3, 3]
[1, 3, 4]
[2, 0, 0]
[2, 0, 1]
[2, 0, 2]
[2, 0, 3]
[2, 0, 4]
[2, 1, 0]
[2, 1, 1]
[2, 1, 2]
[2, 1, 3]
[2, 1, 4]
[2, 2, 0]
[2, 2, 1]
[2, 2, 2]
[2, 2, 3]
[2, 2, 4]
[2, 3, 0]
[2, 3, 1]
[2, 3, 2]
[2, 3, 3]
[2, 3, 4]

The same solution as #Andreeas', just with more explanations (he was faster in posting the answer, I'm adding mine to give myself a reason for the time I spent with the explanations):
import java.util.Arrays;
public class Multiloop {
static public void doSomething(int... maxIndexes) {
// quick check: if any of the maxIndexes is zeo or less
// there's a snowball in a furnace chance for the most inner loop
// to get executed
for(int i=0; i<maxIndexes.length; i++) {
if(maxIndexes[i]<=0) {
return; // nothing to do
}
}
// java guarantees all of then are zero after allocation
int multiIndex[]=new int[maxIndexes.length];
int currIndexPos=maxIndexes.length-1; // start looping with the last
do {
// this happens when the current index reached its correspondent maximum
// which of course is maxIndexes[currIndexPos]-1
while(
currIndexPos>=0 &&
multiIndex[currIndexPos]>=maxIndexes[currIndexPos]-1
) {
currIndexPos--; // search for the prev one to increment
}
if(currIndexPos<0) {
// all the indexes have reached their max value, we are done
break;
}
// if it's not the last index, we need to increment the current one
// and reset to zero all the others following it
if(currIndexPos<maxIndexes.length-1) {
// if not at the max value, then it's safe to increment it
multiIndex[currIndexPos]++;
Arrays.fill(multiIndex, currIndexPos+1, maxIndexes.length, 0);
}
// and now all multicycle indexes are to their proper value
// we reset the currIndexPos to the max and the do what we need to do
currIndexPos=maxIndexes.length-1;
/// Cut along the dotted lines and place your own code
/// ✂...✂...✂...✂...✂...✂...✂...✂...✂...✂
{ // the inner-most cycle, using the multicycle indexes as necessary
// replace it with what you need here
// **** Just don't screw up the currIndexPos!!!
// **** unless you know what you are doing
// **** (e.g. breaking any of the "cycles" on the way)
char nameForIndex='a';
for(int i=0; i<maxIndexes.length; i++) {
if(i>0) {
System.out.print(',');
}
System.out.print(nameForIndex+"="+multiIndex[i]);
nameForIndex++;
}
System.out.println();
}
// ✂...✂...✂...✂...✂...✂...✂...✂...✂...
multiIndex[currIndexPos]++;
} while(true); // the exit condition is handled at the cycle start anyway
}
static public void main(String args[]) {
// a triple cycle with their respective max indexes
doSomething(2,4,3);
}
}
Output:
a=0,b=0,c=0
a=0,b=0,c=1
a=0,b=0,c=2
a=0,b=1,c=0
a=0,b=1,c=1
a=0,b=1,c=2
a=0,b=2,c=0
a=0,b=2,c=1
a=0,b=2,c=2
a=0,b=3,c=0
a=0,b=3,c=1
a=0,b=3,c=2
a=1,b=0,c=0
a=1,b=0,c=1
a=1,b=0,c=2
a=1,b=1,c=0
a=1,b=1,c=1
a=1,b=1,c=2
a=1,b=2,c=0
a=1,b=2,c=1
a=1,b=2,c=2
a=1,b=3,c=0
a=1,b=3,c=1
a=1,b=3,c=2

How about using recursive:
int recursive_loop(int var_M){
if(var_M == destination) return 0;
else{
for(int i=0;i<var_M || recursive_loop(var_M+1) ; i++){
// Do operation here
}
}
}
I tested with C , it work.

Related

Creating subsequences for elements in a LIst

I am creating unique subsequences of size 2 using below code. How can I create subsequences of different sizes. Size would be dynamic.
For example, [1 2 3 4] -> [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
For size 3, it would be , [[1, 2, 3], [1, 2, 4], [2, 3, 4]]
public static int getTheSubseq(List<Integer> AList){
List<List<Integer>> li = new ArrayList<>();
for (int i = 0; i < AList.size(); i++){
for(int j =i+1; j < AList.size(); j++){
List<Integer> temp = new ArrayList<>();
temp.add(AList.get(i));
temp.add(AList.get(j));
li.add(temp);
}
}
System.out.println(li);
return 1;
}
Using recursion you could build the subsequences as follows:
private void buildSubsequence( List<Integer> source, int targetSize,
List<List<Integer>> result, Stack<Integer> currentSubsequence, int currentIndex ) {
//We don't want to iterate beyond the point where we can't build a complete subsequence.
//Thus we'll need to subtract the number of still needed elements
//(target count - number of elements already in the subsequence - 1 for this call)
int maxIndex = source.size() - ( targetSize - currentSubsequence.size() - 1);
//iterate over each index from the current one to this call's max
for( int i = currentIndex; i < maxIndex; i++ ) {
//add the element at that index to the subsequence
currentSubsequence.push( source.get( i ) );
//if we're done make a copy
if( currentSubsequence.size() == targetSize ) {
result.add( new ArrayList<Integer>( currentSubsequence) );
} else { //if we're not done, get the next element
buildSubsequence( source, targetSize, result, currentSubsequence, i + 1 );
}
//remove the last element added by push() to have it replaced with the next one
currentSubsequence.pop();
}
}
Then you call it like this:
List<Integer> source = Arrays.asList( 1,2,3,4,5,6 );
List<List<Integer>> result = new LinkedList<>();
buildSubsequence( source, 3, result, new Stack<>(), 0 );
That creates the following subsequences:
[1, 2, 3]
[1, 2, 4]
[1, 2, 5]
[1, 2, 6]
[1, 3, 4]
[1, 3, 5]
[1, 3, 6]
[1, 4, 5]
[1, 4, 6]
[1, 5, 6]
[2, 3, 4]
[2, 3, 5]
[2, 3, 6]
[2, 4, 5]
[2, 4, 6]
[2, 5, 6]
[3, 4, 5]
[3, 4, 6]
[3, 5, 6]
[4, 5, 6]
Note that this is just one way to solve it. :)

Combinations with replacement Java

For the last couple of days, I am trying to solve this problem of combinations with replacement in java. I checked other languages as well maybe it was done in them and I could translate to java but with no luck, so any help greatly appreciated.
So here is the problem(mock interview question) I came upon:
Combine from range 0 - 6(n)
In an array of size r (let's say 3)
So the formula for combinations with replacement is C(n,r)=(n+r−1)! / r!(n−1)!. In this case the combinations will be 84
000
010,
011,
...,
025,
055,
...,
666.
However, I can't get my head around this algorithm WITH REPLACEMENT which is an entirely different story from without replacement.
Thank you again in advance for your help.
Retrieved first version of answer:
You can use nn=(n+1) variants of digit at every of r places, so overall number of combinations is P = nn^r. Note that every combination corresponds to the number in range 0..P-1.
So you can walk through all integer values in range 0..P-1 and represent loop counter in nn-ary system.
Java code
public static void main (String[] args) throws java.lang.Exception
{
int n = 2;
int r = 3;
int nn = n + 1;
int p = 1;
for (int i=0; i<r; i++)
p *= nn;
for (int i=0; i<p; i++){
int t = i;
String comb = "(";
for (int j=0; j<r; j++){
comb = comb + String.format("%2d, ", t % nn);
t = t / nn;
}
comb = comb.substring(0, comb.length()-2) + ')';
System.out.println(comb);
}
}
Python code:
n = 2
r = 3
nn = n + 1
p = nn**r
for V in range(p):
t = V
comb = []
for i in range(r):
d = t % nn
comb.append(d)
t = t // nn
print(comb)
[0, 0, 0]
[1, 0, 0]
[2, 0, 0]
[0, 1, 0]
[1, 1, 0]
[2, 1, 0]
[0, 2, 0]
[1, 2, 0]
[2, 2, 0]
[0, 0, 1]
[1, 0, 1]
[2, 0, 1]
[0, 1, 1]
[1, 1, 1]
[2, 1, 1]
[0, 2, 1]
[1, 2, 1]
[2, 2, 1]
[0, 0, 2]
[1, 0, 2]
[2, 0, 2]
[0, 1, 2]
[1, 1, 2]
[2, 1, 2]
[0, 2, 2]
[1, 2, 2]
[2, 2, 2]
The second version: for combinations with replacement.
Recursive (the simplest way) generation in Python.
def cwrreq(maxlen, maxx, s):
if len(s)== maxlen:
print(s)
else:
for i in range(maxx + 1):
cwrreq(maxlen, i, s + str(i))
def combwithrepl(maxlen, maxval):
cwrreq(maxlen, maxval, "")
combwithrepl(3, 6)
generates 84 combinations
000
100
110
111
200
...
663
664
665
666
Full list for (3,3).
Meaning: there are three indistinguishable boxes and three kinds of paints (say red, green, blue).
000 all boxes are hollow
100 one box is red
110
111 all boxes are red
200
210 one box is green, another is red
211
220
221
222
300
310
311
320
321 all boxes have distinct colors
322
330
331
332
333 all boxes are blue
private static List<int[]> samples(int n, int k) {
if (k < 0 || n < 0) throw new IllegalArgumentException();
if (k == 0) return Collections.emptyList();
List<Integer> set = new ArrayList<>();
for (int i = 0; i < n; i++) set.add(i);
if (k == 1) return set.stream().map(i -> new int[]{i}).collect(Collectors.toList());
List<int[]> previous = samples(n, k - 1);
List<int[]> out = new ArrayList<>();
for (int i : set) for (int[] array : previous) out.add(glue(i, array));
return out;
}
private static int[] glue(int i, int[] array) {
int[] out = new int[array.length + 1];
out[0] = i;
System.arraycopy(array, 0, out, 1, array.length);
return out;
}
e.g.,
for (int[] sample : samples(2, 3)) {
System.out.println(Arrays.toString(sample));
}
yields
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]
and
for (int[] sample : samples(4, 2)) {
System.out.println(Arrays.toString(sample));
}
yields
[0, 0]
[0, 1]
[0, 2]
[0, 3]
[1, 0]
[1, 1]
[1, 2]
[1, 3]
[2, 0]
[2, 1]
[2, 2]
[2, 3]
[3, 0]
[3, 1]
[3, 2]
[3, 3]

connecting points in n-dimensional hyper cube

I am experimenting with creating 3d like sketches in processing without using the p3d renderer. I have managed to make a cube but for it I hardcoded all the coordinates and connections and once you want to add another dimension it begins to get a little boring. So I have created a function to create all the coordinates:
float[][] cube(int dims, float w) {
int outputSize = (int)pow(2, dims);
float[] temp = new float[dims];
float[][] res = new float[outputSize][dims];
Arrays.fill(temp, w);
res[0] = temp.clone();
for (int i = 0; i < outputSize - 1; i++) {
for (int j = dims - 1; true; j--) {
temp[j] *= -1;
if (temp[j] < 0) {
break;
}
}
res[i + 1] = temp.clone();
}
return res;
}
It simply works by using binary so the inputs (2, 1) cube would be:
[[1, 1], [1, -1], [-1, 1], [-1, -1]]
It works fine but the problem is that It only returns the corners but not witch corner to connect but I can't find an efficient way to do that. I need another function that returns what to indices to connect.
Here is an example of what the function should do given the array above:
[[0, 1], [1, 3], [3, 2], [2, 0]]
(the inner arrays may be in a different order)
Is there any known algorithm to connect the corners of a n-dimensional cube?
I am ok with changing the other function if some other point generation helps.
Here is a way to iteratively generate the coordinates and indices together:
Start with a cube of dimension n
Make two copies of the cube, and place one at each of the extremal coordinates (e.g. -1 and +1) on the n + 1-th axis
Make edges to join each pair of corresponding vertices on the cubes
You already know that the number of vertices V(n) = 2^n. Since the number of edges added to an n + 1 cube is equal to this (all corresponding vertex pairs), plus those of the copied n cube, the recurrence relation for the number of edges is:
E(n) = 2 * E(n - 1) + V(n - 1) // copies + joining edges
E(1) = 1 // base case for n = 1
--> E(n) = n * 2^(n - 1)
n | E(n)
-------------
1 | 1
2 | 4
3 | 12
4 | 32
5 | 80
This allows one to pre-allocate the number of required edges and calculate index offsets when copying the new cube / adding new edges.
Code:
// edge index
class Edge
{
public int A, B;
public Edge(int a, int b)
{
A = a; B = b;
}
public Edge shift(int n)
{
return new Edge(A + n, B + n);
}
}
// cube class
class Cube
{
// I'll leave out the get-functions etc here
private float[][] m_verts;
private Edge[] m_edges;
public Cube(float[][] v, Edge[] e)
{
m_verts = v;
m_edges = e;
}
}
Cube cube_N(int dims, float w)
{
// base case
if (dims < 1)
return null;
// calculate buffer sizes
int dpow2 = 1 << dims;
int numVerts = dpow2;
int numEdges = dims * (dpow2 / 2);
// buffers
float[] temp = new float[dims];
float[][] verts = new float[numVerts][];
Edge[] edges = new Edge[numEdges];
// base case creation
Arrays.fill(temp, w);
verts[0] = temp.clone();
edges[0] = new Edge(0, 1);
// iterative step
for (int i = 0; i < dims; i++)
{
int nV = 1 << i;
int nE = i * (nV / 2);
// copy + shift vertices
for (int j = 0; j < nV; j++)
{
float[] v = verts[j].clone();
v[i] = -w;
verts[nV + j] = v;
}
// copy + shift previous edges
for (int j = 0; j < nE; j++)
{
edges[nE + j] = edges[j].shift(nV);
}
// create new edges to join cube copies
int off = nE * 2;
for (int j = 0; j < nV; j++)
{
edges[off + j] = new Edge(j, nV + j);
}
}
return new Cube(verts, edges);
}
Results for n = 3:
verts:
[1, 1, 1], [-1, 1, 1], [1, -1, 1], [-1, -1, 1],
[1, 1, -1], [-1, 1, -1], [1, -1, -1], [-1, -1, -1]
edges:
[0, 1], [2, 3], [0, 2], [1, 3], [4, 5], [6, 7],
[4, 6], [5, 7], [0, 4], [1, 5], [2, 6], [3, 7]
Results for n = 4:
verts:
[1, 1, 1, 1], [-1, 1, 1, 1], [1, -1, 1, 1], [-1, -1, 1, 1],
[1, 1, -1, 1], [-1, 1, -1, 1], [1, -1, -1, 1], [-1, -1, -1, 1],
[1, 1, 1, -1], [-1, 1, 1, -1], [1, -1, 1, -1], [-1, -1, 1, -1],
[1, 1, -1, -1], [-1, 1, -1, -1], [1, -1, -1, -1], [-1, -1, -1, -1]
edges:
[0 , 1], [2 , 3], [0 , 2], [1 , 3], [4, 5], [6 , 7], [4 , 6], [5 , 7],
[0 , 4], [1 , 5], [2 , 6], [3 , 7], [8, 9], [10, 11], [8 , 10], [9 , 11],
[12, 13], [14, 15], [12, 14], [13, 15], [8, 12], [9 , 13], [10, 14], [11, 15],
[0 , 8], [1 , 9], [2 , 10], [3 , 11], [4, 12], [5 , 13], [6 , 14], [7 , 15]

Why is the array not being sorted?

I'm attempting to incorporate this logic based code with the quicksort into my main program (Not shown here). The program basically generates 2d array values, and proceeds to print them out on the screen. The dim variable serves as the amount of dimensions in this code (I.e 3D) Since there are X,Y,Z coordinates. I'm having trouble understanding if this is the correct way to go about sorting this array using the [dim]. Any constructive/helpful input would be appreciated.
Example output (Not sorting it) (Taken from the last bit of the code to prove each row is not sorted :
[[3, 1, 1, 0], [3, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0], [3, 1, 1, 0], [3, 1, 1, 0], [3, 1, 1, 0], [2, 1, 1, 0], [3, 1, 1, 0], [3, 1, 1, 0]]
[[4, 5, 3, 0], [4, 5, 3, 0], [2, 1, 1, 0], [4, 5, 3, 0], [4, 5, 3, 0], [4, 5, 3, 0], [4, 5, 3, 0], [2, 1, 1, 0], [4, 5, 3, 0], [4, 5, 3, 0]]
[[4, 1, 2, 0], [4, 1, 2, 0], [2, 1, 1, 0], [4, 1, 2, 0], [4, 1, 2, 0], [4, 1, 2, 0], [4, 1, 2, 0], [2, 1, 1, 0], [4, 1, 2, 0], [4, 1, 2, 0]]
The actual program
//import java.util.ArrayList;
import java.util.*;
public class MyQuickSort {
private static int a[][] = new int [10][4];
private static int dim = 3;
public static void main(String[] args) {
for(int i = 0; i < 10; i++) {
//for(int j = 0; j < 4; j++) {
a[i][0] = (int)(Math.random () * 6) +1 ;
a[i][1] = (int)(Math.random () * 6) +1 ;
a[i][2] = (int)(Math.random () * 6) +1 ;
quickSort(a, 0, a.length - 1);
System.out.println(Arrays.deepToString(a));
//}
}
}
public static void quickSort(int[][] a, int p, int r)
{
if(p<r)
{
int q=partition(a,p,r);
quickSort(a,p,q);
quickSort(a,q+1,r);
}
}
private static int partition(int[][] a, int p, int r) {
int x = a[p][dim];
int i = p-1 ;
int j = r+1 ;
while (true) {
i++;
while ( i< r && a[i][dim] < x)
i++;
j--;
while (j>p && a[j][dim] > x)
j--;
if (i < j)
swap(a, i, j);
else
return j;
}
}
private static void swap(int[][] a, int i, int j) {
// TODO Auto-generated method stub
int temp = a[i][dim];
a[i] = a[j];
a[j][dim] = temp;
}
}
Since all of your individual numbers are non-negative single-digit integers, why not just convert your array elements to strings -- that is, [3, 1, 1, 0] as a string -- and quicksort them like that? The sort order will end up being the same as if you looped through each element of the above individually and compared the numerical values.

Java Recursive function with two for loops in it

Inside my program, the most important part is filling an array with some number of objects.
These objects are bishops on a chess board. There are alternative functions to place the bishop and the place it attacked places or decide if the board is filled properly are made.
At the end of the first couple of loops the board is filled and falls back into its previous state where the next attempt is done.
The problem is that somehow it uses not the old array but the last one so that the array keeps piling up numbers in stead of making all the possible options. What am i doing wrong?
EDIT:
Think i have to mention that in the outcome the two is how they are should be. after that this one is counted with no zero in it and CheckGoedeStand returns a one.
int SolveBoard(int m,int n,int d,int l) {
int[][] field = new int[m][n]; // this is the m*n schaakbord. int is standaard 0.
// probleem opgelost
System.out.println("aantal lopers: " + l);
int GoedeStand = Recursie(field,0,0, m, n, d, l);
PrintFieldImage(field);
return GoedeStand;
}
//deze fuctie is alleen gekoppeld saan SolveBoard()
int Recursie(int[][] field, int LopersSet, int AGB, int m, int n, int d, int l) {
int mcount, ncount;
int[][] fieldC = field;
//de rekenlus
// 0 is leeg, 1 is aangevallen, 2 is lopers plaats, 3 is dame haar plaats
if (LopersSet < l) {
LopersSet++;
for (mcount = 0; mcount < m; mcount++) {
for (ncount = 0; ncount < n; ncount++) {
//if (field[mcount][ncount] <= 1) {
fieldC = PlaatsLoper(fieldC, m, n, mcount, ncount);
//nu de recursie, eerst kopie maken van bord zodat deze niet verloren gaat
AGB = Recursie(fieldC, LopersSet, AGB, m, n, d, l);
//}
}
}
} else {
PrintFieldImage(field);
}
if (CheckGoedeStand(field, m, n) == 1 && LopersSet == l) {
//PrintFieldImage(field);
AGB++;
//field = new int[m][n];
}
return AGB;
}
As you can see, I start with an empty array, d is unused, and for the testing I have m, n, and l set as 2.
This is my output:
[2, 0]
[0, 1]
[2, 2]
[1, 1]
[2, 2]
[2, 1]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
[2, 2]
AGB= 19

Categories