3
\$\begingroup\$

The function func(int m,int n) outputs (for m = 3, n = 5):

3

34

345

34

3

I came up with this code:

void func(int m,int n)
{
  for(int i=1;i<n-m+2;i++)
{   int k=i;
  int j=m;

    while(k>0)
  {
    System.out.print(j);
     k--;j++;
   }
 System.out.println("");

}


for(int i=n-m;i>0;i--)
{  int k=i;
  int j=m;

  while(k>0)
  {
  System.out.print(j);
     k--;j++;
   }
System.out.println("");

    }

}

Is there an alternate, better way to do it? Can it be more efficient?

\$\endgroup\$
4
\$\begingroup\$

You can do it recursively:

void func(int m,int n) {
  if (m == n) {
    System.out.println(m);
  } else {
    func(m, n - 1);
    for (int i = m; i <= n; i++) {
      System.out.print(i);
    }
    System.out.println("");
    func(m, n - 1);
  }
}
\$\endgroup\$
2
\$\begingroup\$

Dividing the work over some helper methods with explaining names helps making the code more readable and reduces cyclometic complexity per method.

Use a StringBuilder to compose the result String, as this anbles building the String non sequentially.

Separate the building logic from the output logic, they are two different responsibilities (reasons for change).

I've kept the method name func but I suggest you choose a more meaningful name.

private static final String DOUBLE_NEWLINE = "\n\n";

public void func(int m, int n) {
    System.out.println(buildFuncString(m, n));
}

private String buildFuncString(int m, int n) {
    String fullEnumeration = enumerateFromTo(m, n);
    StringBuilder builder = new StringBuilder(fullEnumeration);
    for (int i = n - m; i > 0; i--) {
        String substring = fullEnumeration.substring(0, i);
        builder.insert(0, DOUBLE_NEWLINE).insert(0, substring);
        builder.append(DOUBLE_NEWLINE).append(substring);
    }
    return builder.toString();
}

private String enumerateFromTo(int m, int n) {
    StringBuilder builder = new StringBuilder();
    for (int i = m; i <= n; i++) {
        builder.append(i);
    }
    return builder.toString();
}
\$\endgroup\$
2
\$\begingroup\$

I'll try solve it using a stack. (I've renamed your function 'func' to 'printWithStack' )

void printWithStack(int m, int n) {

  Stack<Integer> integerStack= new Stack<Integer>();

  // Go uphill, print up to m = n
  for( int i=m ; i<=n; i ++) {          
    if(i <= n) integerStack.push(i);            
    print(integerStack);        
  }

  // Go downhill, print until the stack is empty     
  while(!integerStack.isEmpty()) {
    integerStack.pop();
    print(integerStack);
  }
}

/**
 * Print all the element of the given stack on a line
 */
void print(Stack<Integer> stackToPrint) {
  if(!stackToPrint.isEmpty()) {
    for(Integer element : stackToPrint) System.out.print(element);
    System.out.println();
  }
}
\$\endgroup\$
0
\$\begingroup\$

The recursive looks the cleanest. To extend the normal loop approaches:

public static void printNumbersTriangle(final int start, final int end) {
    if (!(start <= end))
        throw new IllegalArgumentException("Start not <= end. Start: " + start + ", end: " + end);
    int position = start;
    int modifier = 1;
    while (position >= start) {
        printAllNumbersFromStartUntilEndExclusive(start, position);
        position += modifier;
        if (position == end)
            modifier = -1;
    }
}

public static void printAllNumbersFromStartUntilEndExclusive(final int start, final int end) {
    for (int i = start; i <= end; i++)
        System.out.print(i);
    System.out.println();
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.